Надійні резервні копії — це не розкіш, а базова потреба для будь-якого продакшн-середовища. У цій інструкції покажу, як на сервері Linux побудувати стійку систему бекапів на базі BorgBackup і systemd timers. Буде покроково: від встановлення та налаштування до автоматизації, перевірки й відновлення. Підійде як для невеликих VPS, так і для масштабніших інфраструктур на сервер Linux. ✨

Чому саме Borg + systemd timers

BorgBackup — дедуплікований, шифрований і дуже швидкий інструмент для резервного копіювання. Він економить місце, підтримує компресію, має зручний CLI та чудово підходить для резервне копіювання системи і даних. А systemd timers — сучасна альтернатива cron, що краще логґується, відпрацьовує пропущені запуски після рестарту (Persistent) і легко інтегрується з сервісами. Разом це — надійна автоматизація задач без зайвих залежностей.

Передумови та встановлення

Працюємо в терміналі Linux з правами root або через sudo. Для початку встановимо BorgBackup:

# Debian/Ubuntu
sudo apt update && sudo apt install -y borgbackup

# RHEL/CentOS/Fedora
sudo dnf install -y borgbackup

# Arch/Manjaro
sudo pacman -S --noconfirm borg

Рекомендації безпеки: створіть окремого користувача (наприклад, backup) і використовуйте окрему SSH-ключову пару для доступу до віддаленого репозиторію. Це особливо важливо, якщо бекап іде на інший сервер Linux по SSH.

Налаштування сховища та змінних середовища

Визначимо, де зберігати резервні копії. Варіанти: локальний диск або віддалений репозиторій по SSH. Приклад для SSH:

# Приклад шляху до репозиторію (SSH):
# ssh://USER@HOST:PORT/~/repos/server1

sudo mkdir -p /etc/borg
sudo chmod 700 /etc/borg

# Файл зі змінними середовища для сервісу
sudo tee /etc/borg/backup.env >/dev/null <<'EOF'
BORG_REPO="ssh://backup@backup.example.com:22/~/repos/server1"
BORG_PASSPHRASE="сильний-довгий-пароль"
BORG_RSH="ssh -i /etc/borg/backup_ed25519 -o BatchMode=yes -o Compression=no"
# Файл виключень
EXCLUDES="/etc/borg/excludes.txt"
EOF

# Створимо список виключень (тимчасові та кеші)
sudo tee /etc/borg/excludes.txt >/dev/null <<'EOF'
/var/tmp
/var/cache
/var/lib/docker
/proc
/sys
/dev
/run
EOF

sudo chmod 600 /etc/borg/backup.env
# приватний ключ також має бути 600
sudo chmod 600 /etc/borg/backup_ed25519

# Ініціалізація репозиторію (виконайте один раз)
# Якщо репозиторій новий:
export $(grep -v '^#' /etc/borg/backup.env | xargs -d '\n')
borg init --encryption=repokey-blake2 "$BORG_REPO"

Формат repokey-blake2 шифрує дані і зберігає ключ у репозиторії. Не втрачайте BORG_PASSPHRASE — без нього доступ до даних буде неможливий.

Скрипт резервного копіювання

Створимо скрипт, який робить бекап, чистить старі архіви (retention), та компактує репозиторій. Це серце нашої автоматизації задач.

sudo tee /usr/local/sbin/borg-backup.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

# Завантажуємо змінні середовища
if [[ -f /etc/borg/backup.env ]]; then
  # shellcheck disable=SC2046
  export $(grep -v '^#' /etc/borg/backup.env | xargs -d '\n')
else
  echo "Env file /etc/borg/backup.env not found" >&2
  exit 1
fi

TIMESTAMP=$(date +"%Y-%m-%d_%H-%M")
HOSTNAME=$(hostname -s)
ARCHIVE="::${HOSTNAME}-${TIMESTAMP}"

# Не забудьте підготувати дампи БД перед бекапом (наприклад, у /var/backups)

borg create \
  --verbose --stats \
  --compression lz4 \
  --exclude-from "$EXCLUDES" \
  "$BORG_REPO$ARCHIVE" \
  /etc /home /var/www /var/backups

# Залишаємо 7 денних, 4 тижневих, 6 місячних
borg prune -v --list "$BORG_REPO" \
  --keep-daily=7 --keep-weekly=4 --keep-monthly=6

# Оптимізація місця
borg compact "$BORG_REPO"

echo "Backup finished: $ARCHIVE"
EOF

sudo chmod +x /usr/local/sbin/borg-backup.sh

Порада: перед виконанням цього скрипту можна запускати підскрипти дампів БД (PostgreSQL, MariaDB), аби знімки були узгодженими.

Сервіс і таймер systemd

Створимо unit-файли для systemd. Це зручніше та надійніше, ніж cron, а також чудово вписується у сценарії cron та systemd timers.

# Сервіс
sudo tee /etc/systemd/system/borg-backup.service >/dev/null <<'EOF'
[Unit]
Description=BorgBackup: nightly backup job
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/borg/backup.env
ExecStart=/usr/local/sbin/borg-backup.sh
# Щоб не заважати продакшну
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=6
# Безпекові опції
ProtectSystem=full
PrivateTmp=yes
NoNewPrivileges=yes

[Install]
WantedBy=multi-user.target
EOF

# Таймер (щоденно ~03:15 з випадковою затримкою)
sudo tee /etc/systemd/system/borg-backup.timer >/dev/null <<'EOF'
[Unit]
Description=BorgBackup: schedule nightly backup

[Timer]
OnCalendar=03:15
RandomizedDelaySec=20m
Persistent=true
AccuracySec=1m

[Install]
WantedBy=timers.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now borg-backup.timer

# Перевірка стану таймера і сервісу
systemctl list-timers | grep borg-backup
sudo systemctl start borg-backup.service
sudo journalctl -u borg-backup.service -n 200 --no-pager

Persistent=true гарантує, що пропущений запуск (наприклад, через рестарт) буде виконаний при першій нагоді.

Перевірка, цілісність і відновлення

Після першого циклу зробіть перевірку репозиторію та потренуйтеся у відновленні:

# Перевірка списку бекапів
borg list "$BORG_REPO"

# Перевірка цілісності
borg check --verify-data "$BORG_REPO"

# Відновлення окремого каталогу (dry-run + list)
borg extract --dry-run --list "$BORG_REPO::HOST-YYYY-MM-DD_HH-MM" etc/nginx

# Монтоване відновлення (зручно для вибірки файлів)
sudo mkdir -p /mnt/borg
sudo borg mount "$BORG_REPO::HOST-YYYY-MM-DD_HH-MM" /mnt/borg
# ...скопіювали потрібне...
sudo borg umount /mnt/borg

Тренуйтеся відновлювати до тимчасового шляху, щоб упевнитися, що політика виключень імен та права доступу збережені правильно.

Альтернативні способи

  • cron: можна замінити таймери на записи в crontab, але ви втратите журналювання systemd і Persistent-запуски. Зараз краще обирати systemd timers.
  • borgmatic: зручний YAML-обгортка для Borg із вбудованими hooks, healthchecks, ротацією; добре масштабується.
  • restic: альтернатива з подібною філософією, але інший формат сховища та бекенди (S3 і т.д.).

GUI-спосіб: Pika Backup або Vorta

Якщо ви адмініструєте робочі станції або любите графічні інструменти, зверніть увагу на Pika Backup (GNOME) або Vorta. Вони використовують Borg під капотом і дозволяють налаштувати профілі, SSH-репозиторії та розклади.

  1. Встановіть Pika Backup або Vorta на робочій станції.
  2. Створіть новий репозиторій (локальний або SSH), увімкніть шифрування.
  3. Додайте каталоги, які потрібно копіювати, і налаштуйте виключення.
  4. Налаштуйте розклад (scheduler) — це аналог systemd timers, але у GUI.

На headless-сервері краще залишатися на CLI + systemd, але для десктопів це дуже зручно 🙂

FAQ

Що робити, якщо загубився BORG_PASSPHRASE?

На жаль, за своєю природою шифрування Borg не дозволяє відновити дані без пароля або ключів. Зберігайте пароль у менеджері паролів і майте офлайн-копію.

Репозиторій "locked" або завис процес

Використайте borg break-lock "$BORG_REPO" лише якщо впевнені, що інший процес не працює. Причину блокування варто дослідити у журналах.

Доступ по нестандартному SSH-порту

Задайте порт у URL репозиторію або через BORG_RSH: BORG_RSH="ssh -p 2222 -i /etc/borg/backup_ed25519".

"Permission denied" при запуску сервісу

Перевірте права на ключі (600), /etc/borg/backup.env і політики безпеки в unit-файлі (можливо, потрібно послабити ProtectSystem або додати ReadWritePaths=).

Як перевірити, що таймер спрацював?

Подивіться systemctl status borg-backup.timer і журнали journalctl -u borg-backup.service. Також systemctl list-timers показує наступний і останній запуск.

Як підвищити безпеку SSH на стороні сховища?

У authorized_keys для користувача backup на сервері-сховищі використайте примусову команду:

command="borg serve --restrict-to-repository /home/backup/repos/server1",restrict ssh-ed25519 AAAA... ваш_публічний_ключ

Мало місця на репозиторії

Перегляньте політику prune, додайте виключення, увімкніть агресивнішу компресію (zstd,10), або збільшіть сховище.

Порада від Kernelka

Раз на тиждень робіть тестове відновлення на окремий шлях і проганяйте borg check. Дотримуйтесь правила 3-2-1 (3 копії, 2 різні носії, 1 — поза сайтом). Для баз даних — знімайте дампи перед запуском бекапу, або використовуйте snapshot-и LVM/ZFS. Маленький бонус: додайте сповіщення про успіх/помилку у ваш моніторинг або чат-бот — так спатиметься спокійніше 😌

Підсумок

  • Borg забезпечує швидке, шифроване і дедупліковане резервне копіювання.
  • systemd timers — надійніші за cron: логування, Persistent, керування залежностями.
  • Скрипт + сервіс + таймер = повна автоматизація задач без зайвих залежностей.
  • Тестуйте відновлення і контролюйте журнали — бекап хороший лише тоді, коли з нього можна відновитися.
  • Для десктопів зручно використовувати Pika Backup або Vorta (GUI).