Короткий ответ: резервная копия нужна не для «на всякий случай», а для конкретного сценария восстановления. Поэтому начинают не с выбора инструмента, а с ответа на два вопроса: что именно нужно вернуть и за какое время. Резервная копия, которую ни разу не восстанавливали, не считается существующей — проверка восстановлением является частью самой процедуры, а не дополнительным этапом.
Базовое правило — 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 в начале скрипта обязателен: без него ошибка на одном шаге не остановит выполнение, и скрипт завершится с кодом успеха, не сделав копию.
Проверка — обязательная часть
Резервная копия без проверки восстановлением бесполезна: о том, что дамп повреждён или не хватает прав, вы узнаете в момент аварии.
- Проверьте размер и читаемость. Пустой файл дампа — типичный результат неверного пароля или отсутствия прав.
- Восстановите на отдельный сервер или в контейнер. Это единственная настоящая проверка.
- Сверьте данные. Количество записей, суммы, наличие последних загруженных файлов.
- Замерьте время восстановления. Именно эта цифра, а не размер копии, определяет допустимый простой.
- Повторяйте регулярно. Раз в квартал — минимум. Схема, которая работала полгода назад, могла перестать работать после смены пароля.
Полезно хранить копию не только на самом сервере. Выгрузка в объектное хранилище или на другой сервер защищает от полной потери: если сервер будет удалён вместе с диском, локальные копии исчезнут вместе с ним.
Чего делать не стоит
- Хранить копию только на том же сервере. Защищает от случайного удаления, но не от отказа диска.
- Копировать файлы работающей базы. Даёт повреждённый слепок.
- Не ограничивать срок хранения. Диск заполнится, и копирование перестанет работать молча.
- Игнорировать лог. Если скрипт падает каждую ночь, а лог никто не читает, копий нет уже месяц.
- Забывать о правах. Файлы копии с паролями должны быть доступны только владельцу.
Резервное копирование имеет смысл только вместе с базовой защитой сервера — она описана в материале про firewall на VPS. А проверить, что копируется, помогает материал про установку PostgreSQL.
