Скрипт для удобного бекапирования системы на PBS

По мотивам обсуждения в tg группе решил вынести сюда свой микро-проект одного вечера

Для чего это

Простой скрипт для удобного бэкапирования выбранных каталогов linux на сервер PBS с дополнительными плюшками

Требования

  1. Наличие Proxmox Backup Server (ну логично же)
  2. debian based или не только arm64 или amd64

Установка

  1. В PVE уже установлен
  2. Debian arm64 качаем отсюда
  3. Для debian на примере trixie

Устанавливаем подпись репозитория

wge http://download.proxmox.com/debian/pbs-client/dists/trixie/main/binary-amd64/proxmox-archive-keyring_4.0_all.deb
sudo dpkg -i proxmox-archive-keyring_4.0_all.deb

Добавляем репозиторий

sudo tee /etc/apt/sources.list.d/pbs-client.sources > /dev/null <<'EOF'
Types: deb
URIs: http://download.proxmox.com/debian/pbs-client
Suites: trixie
Components: main
Enabled: yes
EOF

Устанавливаем клиента

sudo apt update
sudo apt install proxmox-backup-client

Если ругается на зависимости, например 25.04 ubuntu, то просто устанавливаем статически собранный клиент

sudo apt install proxmox-backup-client-static
  1. Для остальных amd64
sudo wget -P /usr/local/bin https://cloud-pbs.com/wp-content/uploads/2025/06/proxmox-backup-client
sudo chmod +x /usr/local/bin/proxmox-backup-client

Скрипты

pbs_backup_settings

#!/bin/sh
PBC=/usr/bin/proxmox-backup-client
LOG_FILE=/tmp/pbs_backup.log
BACKUP_ID=$(hostname)
NS="hosts"
NOTES="${BACKUP_ID}"
BACKUPS="etc.pxar:/etc corosync.pxar:/etc/pve"
EXCLUDE=""
DETECTION_MODE=metadata
EXTRA_ARGS=""

pbs_backup_secrets

#!/bin/bash
PBS_PASSWORD=YYY 
PBS_REPOSITORY=client@pbs@192.168.0.10:backups
PBS_FINGERPRINT=XXXX

pbs_backup.sh

#!/bin/bash
set -euo pipefail

# Function to check files
check_files() {
    for f in "$@"; do
        if [[ ! -f "$f" ]]; then
            echo "Error: file not found: $f" >&2
            exit 1
        fi
    done
}

# Function to check environment variables
check_env() {
    for var in "$@"; do
        if [[ -z "${!var:-}" ]]; then
            echo "Error: environment variable not set: $var" >&2
            exit 1
        fi
    done
}

dir=$(dirname $0)

check_files "$dir/pbs_backup_secrets" "$dir/pbs_backup_settings"

. $dir/pbs_backup_secrets
. $dir/pbs_backup_settings

check_env "BACKUPS" "PBS_REPOSITORY" "PBS_PASSWORD" "PBS_FINGERPRINT" "DETECTION_MODE"

if [[ -z "BACKUP_ID" ]]; then
        BACKUP_ID=$(hostname)
fi

ts=$(date -u +%s)
iso=$(date -u -d "@$ts" +"%Y-%m-%dT%H:%M:%SZ")
SNAPSHOT="host/${BACKUP_ID}/${iso}"
if [ -n "$NS" ]; then
        ns_op="--ns ${NS}"
else
        ns_op=""
fi

excludes=""
for item in $EXCLUDE ; do
        excludes="${excludes} --exclude ${item}"
done

BACKUPS="$BACKUPS pbs_backup.conf:$dir/pbs_backup_settings"

export PBS_PASSWORD
export PBS_FINGERPRINT
$PBC \
        backup \
        $BACKUPS \
        $excludes \
        --backup-time ${ts} \
        --backup-id $BACKUP_ID \
        ${ns_op} \
        --change-detection-mode $DETECTION_MODE \
        --repository $PBS_REPOSITORY \
        $EXTRA_ARGS \
                > $LOG_FILE 2>&1

if [[ -n "$LOG_FILE" ]]; then
        $PBC snapshot upload-log $SNAPSHOT $LOG_FILE ${ns_op} --repository ${PBS_REPOSITORY} >/dev/null 2>&1
fi

if [[ -n "$NOTES" ]]; then
        $PBC snapshot notes update $SNAPSHOT $NOTES ${ns_op} --repository ${PBS_REPOSITORY} >/dev/null 2>&1
fi

Как пользоваться

Создаем 3 файла, pbs_backup.sh делаем исполняемым
в pbs_backup_settings вносим нужные настройки. Файл содержит настройки бекапирования без чувствительных данных

Параметр Значение Пример значения
PBC Полный путь к бинарнику, например, для крона /usr/bin/proxmox-backup-client
LOG_FILE Путь к логу бекапирования /tmp/pbs_backup.log
BACKUP_ID ID бекапа, уникальное значение для каждого сервера $(hostname)
NS Пространство бекапов, если используете, у меня серваки и виртуалки разнесены hosts
NOTES Заметки, как отображается списке ${BACKUP_ID}
BACKUPS Разделенные пробелами бекапы в формате filenae:pxar:/путь на сервере etc.pxar:/etc corosync.pxar:/etc/pve
EXCLUDE Маска исключения файлов *.log
DETECTION_MODE Режим детекции изменений legacy|data|metadata metadata
EXTRA_ARGS Дополнительные пользовательские аргументы –all-file-systems true

DETECTION_MODE

  • legacy - режим по-умолчанию, минимальная нагрузка на сервер,может генерировать большой трафик и размер архива, читает все файлы с диска, что сильно нагружает его
  • metadata - мой избранный режим, сравнивает дату изменения относительно предыдущего бекапа и загружает только изменения, минимальный трафик и дублирование данных, работает очень быстро, но нагружает сервер бекапов т.к. скачивает метаданные предыдущего бекапа и параллельно создает новый
  • data - самый надежный, но рсурсоемкий, вроде как читает файлы и сравнивает контрольные суммы

в pbs_backup_secrets вносим нужные настройки. Файл содержит ключи доступа

Параметр Значение Пример значения
PBS_PASSWORD Пароль токена доступа qwerty
PBS_REPOSITORY Репозиторий с имемем пользователя client@pbs@10.110.10.130:backups
PBS_FINGERPRINT Снимок ssl сертификата сервера 92:85:9f:87:b0:af:c9:66:a5:88:e1:09:b6:f0:4a:e2:51:cb:de:93:f4:19:f5:74:d0:a2:95:ff:66:ce:17:6d

Взять можно тут


Ну и если создаете пользователя, то настраиваете для него права доступа
image

добавить в crontab

0 */6 * * * /root/pbs_backup.sh

Что делает скрипт

  1. Загружает бекапы на сервер
  2. Загружает лог бекапирования на сервер
  3. Загружает файл с настройками на сервер
  4. Устанавливает заметку для бекапа


Ссылки

Чего не хватает

  1. Не настраивал шифрование

P.S.
Это оптимальная конфигурация для бэкапирования Proxmox ноды

P.P.S.
Скоро подготовлю docker образ

8 лайков

странно, что до сих пор в проксе не сделали меню бекапа

Самого PVE? Оно там не надо by design

почему? :weary_cat:
даже в дешевых китайских свитчах есть сохранение настроек

  1. corosync не бекапим, кластеризируем, на худой конец можно взять одноплатник и сделать из него qdevice
  2. виртуалки и контейнеры бекапим в PBS, вместе с бекапом и конфиг заливается
  3. в сам PVE не лезем, всякие допиливания потенциально могут сломать PVE при обновлении версии, соответственно, мы исходим из того, что это должна быть максимально чистая система, максимум всякие драйвера и проброс железа
  4. PVE ставим на 2 диска в зеркале и zfs
  5. В идеале минимум диска под PVE, виртуалки крутим или на кластерных ФС или на SAN

Это все в идеальном корпоративном мире от proxmox, в итоге при падении одного из серверов

  1. все виртуалкки поднимаются на других серверах
  2. админ разворачивает чистый сервер PVE и добавляет его в кластер
  3. по необходимости виртуалки мигрируют на него обратно

Собственно, так работает ESXi, там гипервизор вообще ставится на USB флешку, которая втыкается внутрь сервера

В рамках хомлабы у большинства пользователей нет отдельной стойки с серверами и дисковой полкой для хранилища, тут приходится находить компромиссы, особенно в плане отказоустойчивости

1 лайк

ну дык в рамках мелкого бизныса тоже нет стоек, хорошо если бекап сервер еще будет работать

я имел в виду бекап настроек, а не весь гипервизор
сейчас там ввели сдн, что я даже толком не разобрался еще в этом, много настроек бывает для ната и вот это все бы сохранять и быстро восстанавливать

Ну вот мой скрипт бекапит настройки, но больше для возможности откатить

Но эти настройки, именно проксмокса, реплицируются между нодами кластера, если один сервер, то можно дампить файл базы (там в телеге была переписка на эту тему)

Видимо, проксмокс считает, что даже в малых офисах есть кластер из минимум 3 серверов, а если у вас 2 сервака, то можно воткнуть в сеть малинку и поставить на нее qdevice

1 лайк

А это устанавливать на PVE?
Проверил - не работает :frowning:
“storing login ticket failed: $XDG_RUNTIME_DIR must be set
Error: unable to read “/mnt/us650/backup/ns/hosts/host/proxmox/owner” - No such file or directory (os error 2)
storing login ticket failed: $XDG_RUNTIME_DIR must be set
Error: unable to update manifest blob - unable to load blob '”/mnt/us650/backup/ns/hosts/host/proxmox/2025-09-23T15:06:27Z/index.json.blob"’ - No such file or directory (os error 2)"

и еще: в скрипте pbs_backup_secrets. В описании тут - pbs_secrets

да, сам клиент есть, только скрипты надо скопировать

Не придумал правильного решения пока, иногда вылазит, но на работу не влияет

Не заполнена переменная окружения PBS_REPOSITORY в настройках, скорее всего проблема в следующем

Да, точно, спасибо за уточнение, с settings аналогично, поэтому и предыдущая ошибка была т.к. не подтягиваются переменные,

файлы

  • pbs_backup_settngs
  • pbs_backup_secrets
  • pbs_backup.sh

Добавил проверку на наличие нужных файлов и переменных окружения

Эти ошибки вылезли после переименования файла.
P.s. сделал ручками резервное копирование ветки /etc

  1. Через proxmox backup client.
  2. И на всякий случай tar.gz

попробуйте текущую версию

Не очень понял: если клиент есть на proxmox (бэкап в pbs виртуалок и контейнеров настроил через gui proxmox), то зачем какие то debian и трикси?

Потому что proxmox-backup-client может не только виртуалки бэкапить. У меня ещё рабочий мой комп подключен и каждые 6 часов бекапится на на PBS, ставил на одноплатник ещё отдельно + перевожу потихоньку все сервисы на самобэкап.
Надо понимать, что бэкапированик работающей виртуалки не гарантирует, что после восстановления какой-нить постгрес запустится и будет работать, идеальная схема через промежуточную остановку виртуалки.
А тот же immich и komodo у меня штатными средствам самого сервиса создаёт бэкап на диске, в эти файлы потом уже льются в PBS

извиняюсь, не понял, где вы устанавливаете дебиан? на VM? потом в ней клиент PBS, который бэкапит все?

  1. На компе, с которого сейчас пишу это сообщение установлена Ubuntu 25.04, подключил репозиторий, поставил статический pbc (т.к. у динамического проблемы с зависимостями) и им бекаплю файлы на сервер PBS

  2. одноплатник на armbian, поставил туда arm версию и тоже бекаплю на PBS

  3. в сервисах, которые в докере, например, authentik

services:
  postgresql:
    image: docker.io/library/postgres:16-alpine
    restart: unless-stopped
    volumes:
      - ./database:/var/lib/postgresql/data
      - ./db_backups:/db_backups/
  
  server:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.1}
    volumes:
      - ./media:/media
      - ./custom-templates:/templates
  
  proxmox-backup-client:
    image: fdrake/proxmox-backup-client:latest
    env_file:
      - secrets/proxmox-backup-client.env
    environment:
      - BACKUP_TARGETS=db.pxar:/mnt/db_backups media.pxar:/mnt/media
      - CRON_SCHEDULE=15 2 * * *
      - CUSTOM_HOST=authentik --ns apps
    tmpfs: /tmp
    volumes:
      - ./db_backups/:/mnt/db_backups
      - ./media/:/mnt/media

и do_backup.sh

#!/bin/sh
docker compose exec postgresql sh -c "pg_dump -U authentik authentik > /db_backups/db.sql"
gzip db_backups/db.sql

Соответственно, делается самый правильный бэкап постги в файл и он бэкапится совместно с медиафайлами.

В PBS это выглядит так

Да, я храню БД рядом с сервисами, пока не решился на разворачивание отдельно жирного инстанса СУБД и хостинга в нем баз всех сервисов

2 лайка