Резервные копии VPS: стратегии и инструменты
На VPS резервные копии — ваша забота, даже если в тарифе написано «бэкапы включены». Разбираем, что именно копировать, почему снимка у хостера мало, как настроить restic или BorgBackup за полчаса и как убедиться, что из копии действительно можно восстановиться.
Копию обычно вспоминают в момент, когда она нужна: обновление сломало базу, кто-то удалил папку сайта, диск у хостера вышел из строя или сервер взломали. В каждом из этих случаев спасает не любая копия, а та, что лежит в другом месте, сделана недавно и из которой вы хоть раз восстанавливались. Ниже — как такую копию устроить на обычном Linux-сервере.
Снимок у хостера — ещё не стратегия
Многие хостеры предлагают снимки диска (snapshot) и автоматические копии в панели. Это полезно, но у такой копии три слабых места.
- Она лежит у того же хостера. Ошибка оплаты, закрытие аккаунта, авария в дата-центре или украденный пароль от кабинета уносят и сервер, и все его снимки сразу.
- Копий мало и они редкие. Часто это одна-две последние копии раз в сутки или в неделю. Если поломку заметили через несколько дней, исправной версии может уже не остаться.
- База в снимке не всегда цела. Снимок фиксирует диск в произвольный момент, как будто сервер внезапно выключили. InnoDB и PostgreSQL обычно после такого восстанавливаются, но гарантии нет, а таблицы MyISAM могут оказаться повреждены.
Снимок удобен как быстрая точка отката перед обновлением. Основные копии стоит делать своими средствами и хранить отдельно.
Правило 3-2-1
Классическая схема звучит так: три копии данных, на двух разных носителях или системах, одна из них — в другом месте. Для VPS это обычно выглядит так:
- Рабочие данные на самом сервере.
- Копия на другом сервере или в объектном хранилище S3 у другого хостера или хотя бы в другом дата-центре.
- Ещё одна копия: снимки в панели хостера, второй сервер копий или выгрузка на домашний накопитель.
К этому стоит добавить одно правило: хотя бы одну копию нельзя удалить с самого рабочего сервера. Если злоумышленник получил root, он видит и пароли к хранилищу копий. Как это устроить, разобрано ниже в разделе о защите от удаления.
Что копировать
Систему целиком копировать обычно не нужно: чистый сервер поднимается из шаблона за минуты. Ценны данные и настройки.
| Что | Где обычно лежит | Как копировать |
|---|---|---|
| Файлы сайтов и загрузки пользователей | /var/www, /home | Файлами |
| Базы данных | /var/lib/mysql, /var/lib/postgresql | Только дампом, не файлами |
| Настройки системы и служб | /etc | Файлами, вместе с сертификатами из /etc/letsencrypt |
| Задания по расписанию | /etc/cron.d, crontab -l пользователей | Файлами или выгрузкой в текст |
| Данные контейнеров | Тома Docker, обычно /var/lib/docker/volumes | Файлами при остановленном контейнере или дампом базы из него |
Исключите кеши, временные файлы, журналы и node_modules: они раздувают копию и восстанавливаются сами.
Базы данных: только дампом
Копировать файлы базы работающего сервера нельзя: в момент копирования они меняются, и копия получится несогласованной. Правильный путь — дамп. Для MySQL и MariaDB:
mysqldump --single-transaction --routines --triggers shop | gzip > /var/backups/shop-$(date +%F).sql.gz
Флаг --single-transaction делает согласованный дамп таблиц InnoDB без остановки записи. Таблицы MyISAM этот флаг не защищает: если они есть, переведите их на InnoDB или делайте дамп с --lock-all-tables. В Debian и Ubuntu root входит в MariaDB без пароля через сокет, поэтому команда от root работает как есть; для другого пользователя положите логин и пароль в ~/.my.cnf с правами 600.
Для PostgreSQL:
sudo -u postgres pg_dump -Fc shop > /var/backups/shop-$(date +%F).dump
sudo -u postgres pg_dumpall --globals-only > /var/backups/pg-globals.sql
Второй файл сохраняет роли и права, которых нет в дампе отдельной базы. Восстанавливают такой дамп командой pg_restore -d shop файл.dump. Если база весит десятки гигабайт и дамп идёт слишком долго, смотрите на физическое копирование: mariabackup или Percona XtraBackup для MySQL, pgBackRest для PostgreSQL.
Дампы складывайте в одну папку, например /var/backups, и включайте её в файловую копию — тогда всё уходит в хранилище одной командой.
Инструменты: rsync, restic, BorgBackup
| rsync | restic | BorgBackup | |
|---|---|---|---|
| Версии копий | Только вручную через --link-dest | Да, снимки | Да, архивы |
| Шифрование | Нет, только при передаче по SSH | Всегда, на стороне сервера-источника | Да, по выбору при создании хранилища |
| Дедупликация | Нет | Да | Да, плюс сжатие |
| Куда сохранять | Диск, SSH | Диск, SFTP, S3, свой REST-сервер | Диск, SSH с borg на той стороне |
| Режим «только добавлять» | Нет | Через rest-server | Через borg serve --append-only |
rsync: зеркало, а не копия
rsync быстро синхронизирует папки, но сам по себе копией не является: удалённый или испорченный файл на сервере при следующем запуске так же удалится или испортится в зеркале. Версии можно получить с флагом --link-dest: каждый запуск создаёт новую папку, а неизменившиеся файлы в ней — жёсткие ссылки на предыдущую, так что место тратится только на изменения. Удобнее запускать это на сервере копий, который сам забирает данные с рабочего:
rsync -a --delete --link-dest=/backup/web/2026-10-30 root@web.example.com:/var/www/ /backup/web/2026-10-31/
Для одного сайта этого хватает, но шифрования и проверки целостности rsync не даёт.
restic
restic — одна программа без зависимостей. Он шифрует данные до отправки, хранит только новые куски файлов и умеет писать на SFTP, в S3-совместимое хранилище или на свой rest-server. Хранилище создаётся один раз, дальше копия делается одной командой:
export RESTIC_REPOSITORY=sftp:backup@storage.example.com:/srv/restic/web1
export RESTIC_PASSWORD_FILE=/root/.restic-pass
restic init
restic backup /etc /var/www /var/backups --exclude-caches
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic check
Команда forget оставляет 7 ежедневных, 4 еженедельных и 6 ежемесячных снимков, а --prune освобождает место от остальных. Без пароля из /root/.restic-pass хранилище не расшифровать никак, поэтому храните его копию вне сервера, например в менеджере паролей.
BorgBackup
Borg похож на restic, но обычно лучше сжимает и быстрее работает с большим числом мелких файлов. Хранилище он держит на диске или на другом сервере по SSH, и там тоже должен стоять borg; S3 он напрямую не поддерживает. Стабильная ветка в 2026 году — 1.4, версия 2.0 пока в бета-тестировании и для рабочих копий не рекомендуется. Команды для 1.4:
export BORG_REPO=ssh://backup@storage.example.com/./web1
export BORG_PASSCOMMAND="cat /root/.borg-pass"
borg init --encryption=repokey-blake2
borg create --stats --compression zstd ::'{hostname}-{now}' /etc /var/www /var/backups
borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6
borg compact
С 1.2 место после prune освобождается только командой compact. В режиме repokey ключ хранится в самом хранилище под паролем; на всякий случай выгрузите его командой borg key export и сохраните вне сервера.
Если на сервере стоит панель управления, посмотрите её встроенные копии: в ISPmanager, FASTPANEL и aaPanel они настраиваются в интерфейсе и умеют отправлять архивы на внешнее хранилище. Подборки тарифов с панелями: ISPmanager, FASTPANEL, aaPanel.
Где хранить копии
- Отдельный VPS у другого хостера. Для копий не нужен быстрый процессор, нужен объёмный диск. Такие тарифы собраны в подборках VPS для хранения данных, VPS с HDD и VPS для резервных копий.
- Объектное хранилище S3. Платите за занятые гигабайты, restic пишет туда напрямую. Если хранилище поддерживает версии объектов или запрет удаления на срок, это ещё и защита от удаления.
- Домашний или офисный накопитель. Хорош как третья копия: сервер копий сам забирает данные по SSH, а снаружи к нему не подключиться.
Если в базе есть персональные данные россиян, учитывайте 152-ФЗ: копии тоже лучше держать на серверах в России, подборка — VPS для 152-ФЗ.
Защита от удаления
Самая неприятная ситуация — когда злоумышленник или ошибочный скрипт удаляет и данные, и копии. Есть три способа этого не допустить.
- Забирать, а не отправлять. Сервер копий сам подключается к рабочему серверу и забирает данные. У рабочего сервера нет никакого доступа к копиям.
- Режим «только добавлять». Для borg на сервере копий в
authorized_keysключу рабочего сервера задаётся команда:command="borg serve --append-only --restrict-to-path /srv/borg/web1",restrict ssh-ed25519 AAAA…. Новые архивы добавлять можно, удалять старые нельзя. Для restic то же делает rest-server, запущенный с флагом--append-only. Чистку старых копий в этом случае запускают с доверенной машины другим ключом. - Версии и запрет удаления в S3. Хранилище само сохраняет предыдущие версии объектов на заданный срок.
Расписание и как часто копировать
Частота зависит от того, сколько данных вы готовы потерять. Для блога хватит копии раз в сутки. Для магазина, где заказы идут весь день, дамп базы стоит делать каждый час, а файлы — раз в сутки. Запускайте копию по cron или таймеру systemd ночью, например файлом /etc/cron.d/backup со строкой 30 3 * * * root /usr/local/bin/backup.sh.
Копия, которая тихо перестала делаться, хуже, чем отсутствие копии: вы думаете, что защищены. В конце скрипта отправляйте сигнал во внешний мониторинг (обычный curl на адрес проверки), и если сигнал не пришёл вовремя, мониторинг напишет вам.
Проверьте восстановление
Раз в месяц восстанавливайте копию на чистый сервер и проверяйте, что сайт открывается и данные на месте. Для этого удобна почасовая оплата: тестовый сервер оплачивается только за часы, пока он работает.
restic restore latest --target /tmp/restore --include /var/www/site
restic check --read-data-subset=10%
borg extract ::web1-2026-10-31T03:30:00 var/www/site # имя архива — из borg list
borg check --verify-data
Вторая и четвёртая команды читают сами данные в хранилище, а не только его оглавление, и находят испорченные куски. Запишите порядок восстановления в отдельный файл вне сервера: в момент аварии вспоминать команды некогда. Как подготовить новый сервер, на который вы будете восстанавливаться, описано в статье Первые 10 шагов после покупки VPS, а перенос сайта целиком — в статье Как перенести сайт с хостинга на VPS.