Резервное копирование VPS: rsync, restic, cron Перейти к содержимому
+7 (920) 556-26-91 пн–пт: 10:00–19:00 (МСК)
Проконсультироваться Обсудить задачу

Инструкции

Резервное копирование VPS: rsync, restic и проверка

Что копировать на VPS, как делать согласованные дампы базы, автоматизация через cron и почему копию обязательно нужно проверять восстановлением.

Резервное копирование VPS: rsync, restic и проверка

Короткий ответ: резервная копия нужна не для «на всякий случай», а для конкретного сценария восстановления. Поэтому начинают не с выбора инструмента, а с ответа на два вопроса: что именно нужно вернуть и за какое время. Резервная копия, которую ни разу не восстанавливали, не считается существующей — проверка восстановлением является частью самой процедуры, а не дополнительным этапом.

Базовое правило — 3-2-1: три копии данных, на двух разных носителях, одна из которых хранится вне основного сервера. Копия на том же диске, что и данные, защищает только от случайного удаления, но не от отказа диска.

Что копировать

Что Как Почему важно
База данных Логический дамп: pg_dump, mysqldump Копирование файлов работающей базы даёт повреждённый слепок
Файлы сайта rsync или архив Загруженные файлы, изображения, документы
Конфигурации /etc/nginx, конфиги служб Восстановление сервера с нуля без них занимает часы
Переменные окружения Файлы .env, секреты Без них приложение не запустится, даже если код на месте
Задания по расписанию crontab -l, таймеры systemd Забытая автоматика перестаёт работать незаметно
Конфигурация firewall Правила ufw, fail2ban Иначе сервер окажется открыт наружу

Отдельно стоит выгрузить список установленных пакетов: dpkg --get-selections > packages.txt. Это ускоряет восстановление окружения на новом сервере.

Дамп базы данных

PostgreSQL:

pg_dump -U borig -Fc borig_db > /var/backups/borig_db_$(date +%F).dump

MySQL:

mysqldump --single-transaction --routines --triggers 
  -u borig -p borig_db > /var/backups/borig_db_$(date +%F).sql

Флаг --single-transaction для MySQL и режим -Fc для PostgreSQL дают согласованный слепок без остановки базы. Копировать файлы данных работающей базы напрямую нельзя: слепок будет внутренне противоречивым, и восстановление может дать повреждённую базу.

Файлы: rsync

rsync -aAXH --delete 
  --exclude 'cache/' 
  --exclude 'node_modules/' 
  /var/www/ /backup/www/

Ключи -aAXH сохраняют права, владельцев, расширенные атрибуты и жёсткие ссылки. Без них восстановленный сайт может не запуститься из-за неверных прав. Ключ --delete удаляет из копии файлы, удалённые из источника, — без него копия постепенно превращается в свалку.

Инкрементальные копии: restic

rsync хранит полную копию и не умеет версию на прошлую неделю. Для версионирования удобнее restic: он шифрует копии, хранит их инкрементально и умеет подключать удалённые хранилища.

apt install -y restic

export RESTIC_REPOSITORY=/backup/restic
export RESTIC_PASSWORD='длинный_пароль'

restic init
restic backup /var/www /etc/nginx --exclude 'cache'
restic snapshots
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

Команда forget --prune удаляет старые снимки по политике хранения. Без неё хранилище растёт бесконечно.

Автоматизация

Скрипт /usr/local/bin/backup.sh:

#!/usr/bin/env bash
set -euo pipefail
DATE=$(date +%F)
DEST=/var/backups

mkdir -p "$DEST"
pg_dump -U borig -Fc borig_db > "$DEST/db_$DATE.dump"
rsync -aAXH --delete /var/www/ /backup/www/
restic backup /var/www /etc/nginx "$DEST"
restic forget --keep-daily 7 --keep-weekly 4 --prune
find "$DEST" -name '*.dump' -mtime +14 -delete
echo "backup ok $DATE"

Запуск по расписанию — через cron:

0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Ключ set -euo pipefail в начале скрипта обязателен: без него ошибка на одном шаге не остановит выполнение, и скрипт завершится с кодом успеха, не сделав копию.

Проверка — обязательная часть

Резервная копия без проверки восстановлением бесполезна: о том, что дамп повреждён или не хватает прав, вы узнаете в момент аварии.

  1. Проверьте размер и читаемость. Пустой файл дампа — типичный результат неверного пароля или отсутствия прав.
  2. Восстановите на отдельный сервер или в контейнер. Это единственная настоящая проверка.
  3. Сверьте данные. Количество записей, суммы, наличие последних загруженных файлов.
  4. Замерьте время восстановления. Именно эта цифра, а не размер копии, определяет допустимый простой.
  5. Повторяйте регулярно. Раз в квартал — минимум. Схема, которая работала полгода назад, могла перестать работать после смены пароля.

Полезно хранить копию не только на самом сервере. Выгрузка в объектное хранилище или на другой сервер защищает от полной потери: если сервер будет удалён вместе с диском, локальные копии исчезнут вместе с ним.

Чего делать не стоит

  • Хранить копию только на том же сервере. Защищает от случайного удаления, но не от отказа диска.
  • Копировать файлы работающей базы. Даёт повреждённый слепок.
  • Не ограничивать срок хранения. Диск заполнится, и копирование перестанет работать молча.
  • Игнорировать лог. Если скрипт падает каждую ночь, а лог никто не читает, копий нет уже месяц.
  • Забывать о правах. Файлы копии с паролями должны быть доступны только владельцу.

Резервное копирование имеет смысл только вместе с базовой защитой сервера — она описана в материале про firewall на VPS. А проверить, что копируется, помогает материал про установку PostgreSQL.