Главная → Домашний сервер без боли → часть 3

Автоматический бэкап домашнего сервера: restic и таймер systemd

Ночное резервное копирование с шифрованием и историей снимков: restic, служба и таймер systemd, выгрузка базы данных перед копией, проверка восстановления. Всё проверено на чистом Debian 12.

Сначала бэкап. Всегда. Эту фразу каждый админ хоть раз произносил вслух — обычно в тот момент, когда бэкапа как раз не оказалось. Давайте сделаем так, чтобы с вами этого не случилось: настроим автоматическое резервное копирование домашнего сервера, которое работает само, шифрует данные и хранит историю.

Инструмент — restic, бесплатная программа для резервного копирования с открытым кодом. Копии она складывает в репозиторий — так называется хранилище копий, по сути каталог на диске. Каждая копия называется снимком: это состояние ваших файлов на момент запуска.

Что получим и что нужно заранее

Результат: каждую ночь сервер сам сохраняет нужные каталоги в зашифрованный репозиторий, хранит 7 ежедневных, 4 еженедельных и 6 ежемесячных копий, а старые удаляет. Всё это — на restic и таймере systemd, без самописных скриптов в cron.

Нужно:

Что именно сохранять

Прежде чем набирать команды, решим, что копировать. Типичный домашний сервер:

Не нужно копировать саму систему (/usr, /var/cache): её проще поставить заново, чем восстанавливать.

Отдельно про базы данных. Файлы работающей базы — PostgreSQL, MySQL — нельзя просто скопировать: в момент копирования база пишет в них, и копия может оказаться несогласованной. Правильно — сначала выгрузить базу в файл её собственным инструментом (pg_dump, mysqldump), а уже этот файл отдать restic. Как это встроить в службу — покажу в конце.

Шаг 1. Ставим restic

sudo apt update
sudo apt install restic

Ставит restic из штатного репозитория дистрибутива.

restic version

Показывает установленную версию — убедимся, что всё на месте.

Шаг 2. Пароль и настройки в одном месте

Restic шифрует всё, что сохраняет. Ключ шифрования — ваш пароль. Что тут происходит, если пароль потерять? Ровно то, что вы подумали: данные не восстановить никак. Поэтому пароль храним в файле и дополнительно записываем в менеджер паролей.

sudo mkdir -p /etc/restic
sudo sh -c 'head -c 32 /dev/urandom | base64 > /etc/restic/password'
sudo chmod 600 /etc/restic/password

Создаём каталог настроек, генерируем случайный пароль в файл и закрываем его от всех, кроме root.

sudo tee /etc/restic/env >/dev/null <<'EOF'
RESTIC_REPOSITORY=/mnt/backup/restic
RESTIC_PASSWORD_FILE=/etc/restic/password
EOF
sudo chmod 600 /etc/restic/env

Файл с переменными окружения: где лежит репозиторий и где взять пароль. Его потом прочитает systemd.

Шаг 3. Создаём репозиторий

sudo sh -c 'set -a; . /etc/restic/env; restic init'

Загружаем переменные из файла и инициализируем пустой зашифрованный репозиторий в /mnt/backup/restic.

Шаг 4. Первая копия руками

sudo sh -c 'set -a; . /etc/restic/env; restic backup /etc /home /srv --exclude-caches'

Сохраняем /etc, /home и /srv; каталоги с меткой кэша (файл CACHEDIR.TAG) пропускаем. Список каталогов поправьте под себя.

sudo sh -c 'set -a; . /etc/restic/env; restic snapshots'

Показывает список снимков — должен появиться первый.

Первая копия идёт долго: restic читает всё целиком. Следующие будут быстрыми — он сохраняет только изменившиеся куски файлов.

Шаг 5. Служба systemd

sudo tee /etc/systemd/system/restic-backup.service >/dev/null <<'EOF'
[Unit]
Description=Резервная копия restic
RequiresMountsFor=/mnt/backup

[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env
CacheDirectory=restic
Environment=RESTIC_CACHE_DIR=/var/cache/restic
ExecStart=/usr/bin/restic backup /etc /home /srv --exclude-caches
ExecStartPost=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
Nice=10
IOSchedulingClass=idle
EOF

Описываем, что запускать. Разберём по строкам:

Шаг 6. Таймер

sudo tee /etc/systemd/system/restic-backup.timer >/dev/null <<'EOF'
[Unit]
Description=Ежедневная резервная копия restic

[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=15min
Persistent=true

[Install]
WantedBy=timers.target
EOF

Запуск каждый день в 03:00 со случайной задержкой до 15 минут. Persistent=true — если сервер был выключен ночью, копия выполнится сразу после включения.

sudo systemd-analyze verify /etc/systemd/system/restic-backup.service /etc/systemd/system/restic-backup.timer

Проверяем оба файла на ошибки до включения. Тишина в ответ — значит, всё в порядке.

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

Перечитываем конфигурацию systemd и включаем таймер — сейчас и после каждой перезагрузки.

systemctl list-timers restic-backup.timer

Показывает, когда таймер сработает в следующий раз и когда срабатывал в последний.

Шаг 7. Проверяем, что копия восстанавливается

Бэкап, из которого ни разу не восстанавливали, — это надежда, а не бэкап. Проверим.

sudo systemctl start restic-backup.service
journalctl -u restic-backup.service -n 30

Запускаем службу вручную и смотрим последние строки её журнала — там будет отчёт restic о сохранённых файлах.

sudo sh -c 'set -a; . /etc/restic/env; restic restore latest --target /tmp/restore --include /etc/hostname'

Восстанавливаем из последнего снимка один файл во временный каталог /tmp/restore — оригинал не трогаем.

sudo sh -c 'set -a; . /etc/restic/env; restic check'

Проверяем целостность репозитория. Делайте это хотя бы раз в месяц.

Шаг 8. Если на сервере есть база данных

Добавим перед копией выгрузку базы. Пример для PostgreSQL:

sudo mkdir -p /srv/dumps
sudo chown postgres:postgres /srv/dumps
sudo chmod 700 /srv/dumps

Каталог для выгрузок внутри /srv — значит, restic подхватит его автоматически. Последняя команда закрывает каталог от всех, кроме владельца: без неё дамп со всеми базами сможет прочитать любой пользователь сервера. Restic работает от root и прочитает его в любом случае.

sudo systemctl edit restic-backup.service

Открывает файл дополнений к службе — исходный файл остаётся нетронутым. Впишите:

[Service]
ExecStartPre=/usr/sbin/runuser -u postgres -- pg_dumpall --file=/srv/dumps/all.sql

Перед каждой копией выгружаем все базы от имени пользователя postgres в один файл. Если выгрузка не удалась, служба остановится и копия не будет сделана, — ошибку вы увидите в journalctl.

Сам дамп на сервере не зашифрован — шифрует restic уже в репозитории. Поэтому так важен chmod 700 выше. Для MySQL и MariaDB строка будет такой же по смыслу, только с mysqldump --all-databases.

Если что-то пошло не так

И последнее. Один диск в той же квартире защищает от сломавшегося накопителя, но не от пожара и не от кражи. Когда этот бэкап заработает, следующим шагом сделайте вторую копию — вне дома. Restic умеет писать и на удалённые хранилища, но это уже тема отдельной статьи.

Это третья часть цикла «Домашний сервер без боли». Предыдущая — «Docker Compose на домашнем сервере». В следующей части — мониторинг: сервер сам сообщит, если бэкап не выполнился.

#linux#бэкап#restic#systemd
← Docker Compose на домашнем сервере: первый сервис и его обновлениеМониторинг домашнего сервера: письма о дисках, месте и упавших службах →