Данные теряют не только из-за сбоя диска. Чаще всё проще: неудачное обновление движка, rm -rf не в той папке, кривая миграция базы, взлом через старый плагин, ошибка в скрипте выгрузки, который перезаписал таблицу пустыми значениями.
Во всех этих случаях спасает одно — свежая копия, до которой можно откатиться.
Настройка занимает минут десять и дальше работает сама. Ниже — три уровня: от простого к надёжному, выбирайте по ценности данных.
Правило 3-2-1
Классическая схема резервного копирования:
- 3 копии данных
- на 2 разных носителях
- 1 копия — вне основной площадки
Для VPS это означает: рабочие данные на сервере, локальная копия рядом, и ещё одна — во внешнем хранилище. Третий пункт важнее всех остальных: если сервер потерян целиком или к нему получил доступ посторонний, локальные копии не помогут.
Что бэкапить
| Что | Где обычно лежит |
|---|---|
| Файлы сайта или приложения | /var/www, /opt/проект |
| База данных | дамп через mysqldump / pg_dump |
| Конфиги веб-сервера | /etc/nginx |
| Файлы служб systemd | /etc/systemd/system |
| Задания cron | crontab -l |
| SSL-сертификаты | /etc/letsencrypt |
Про последние три строки забывают чаще всего. Файлы и база восстанавливаются, а сервер не запускается — потому что нет конфига nginx и файла службы.
Не бэкапьте то, что скачивается заново: node_modules, venv, папку vendor, образы Docker. Это раздувает архивы в разы без всякой пользы.
Уровень 1. Снапшоты в панели
Самый быстрый вариант: снимок всего диска через панель управления. Делается в пару кликов, восстанавливает сервер целиком на состояние определённого момента.
Плюсы: ничего не нужно настраивать, восстановление занимает минуты, поднимается вся система вместе с настройками.
Минусы: снапшот — это всё или ничего. Достать из него один случайно удалённый файл или вчерашнюю версию одной таблицы не получится. И хранится он на той же инфраструктуре, что и сам сервер.
Снапшоты удобны как страховка перед рискованным действием — обновлением системы, миграцией базы, установкой нового движка. Сделайте снимок, проведите работы, убедитесь, что всё живо.
Как основной и единственный способ бэкапа снапшоты не годятся. Дальше — то, что должно работать постоянно.
Уровень 2. Свой скрипт и cron
Классическая схема: раз в сутки архивируются файлы и дамп базы, старые копии удаляются автоматически.
Создайте скрипт:
nano /opt/backup.sh
#!/bin/bash
set -e
BACKUP_DIR="/opt/backups"
DATE=$(date +%F)
KEEP_DAYS=7
mkdir -p "$BACKUP_DIR"
# база данных
mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" --single-transaction --all-databases \
| gzip > "$BACKUP_DIR/db-$DATE.sql.gz"
# файлы сайта
tar -czf "$BACKUP_DIR/www-$DATE.tar.gz" \
--exclude='*/node_modules' \
--exclude='*/venv' \
--exclude='*/cache' \
/var/www
# конфиги, службы и сертификаты
tar -czf "$BACKUP_DIR/config-$DATE.tar.gz" \
/etc/nginx /etc/systemd/system /etc/letsencrypt 2>/dev/null
# задания cron
crontab -l > "$BACKUP_DIR/crontab-$DATE.txt" 2>/dev/null || true
# удалить копии старше недели
find "$BACKUP_DIR" -type f -mtime +$KEEP_DAYS -delete
echo "$(date '+%F %T') backup ok"
Строка set -e обрывает скрипт на первой же ошибке — это важно. Без неё сломавшийся mysqldump не помешает скрипту дойти до конца и бодро отрапортовать об успехе, хотя дамп будет пустым.
Пароль базы держим не в скрипте, а в отдельном файле:
nano /opt/backup.env
MYSQL_ROOT_PASSWORD=ваш_пароль
chmod 600 /opt/backup.env
chmod +x /opt/backup.sh
Проверьте вручную:
set -a && source /opt/backup.env && set +a
/opt/backup.sh
ls -lh /opt/backups/
Если архивы на месте и весят разумно — ставим на расписание:
crontab -e
30 4 * * * . /opt/backup.env && /opt/backup.sh >> /var/log/backup.log 2>&1
Каждую ночь в 4:30, с записью вывода в лог. Ошибки тоже попадут в лог — благодаря 2>&1.
Проверить, что бэкапы действительно делаются
Молча сломавшийся бэкап — самый неприятный сценарий: все уверены, что копии есть, а их нет уже месяц.
Раз в неделю смотрите лог и даты файлов:
tail -20 /var/log/backup.log
ls -lh /opt/backups/
Надёжнее — настроить внешнее уведомление. Бесплатные сервисы вроде healthchecks.io присылают письмо, если скрипт не отчитался вовремя. Добавьте в конец скрипта:
curl -fsS -m 10 https://hc-ping.com/ВАШ_КЛЮЧ > /dev/null
Благодаря set -e строка выполнится только если всё прошло успешно. Сломался бэкап — пинга нет — приходит уведомление.
Уровень 3. Копии вне сервера
Копии рядом с данными не защищают от потери самого сервера. Нужна выгрузка наружу.
Инструмент под эту задачу — restic: шифрует данные на стороне клиента, хранит только изменения (повторные копии занимают мало места) и умеет работать с S3-совместимыми хранилищами.
apt install restic -y
Настройте доступы:
nano /opt/restic.env
export RESTIC_REPOSITORY="s3:https://s3.провайдер.com/имя-бакета"
export RESTIC_PASSWORD="длинный_пароль_шифрования"
export AWS_ACCESS_KEY_ID="ключ"
export AWS_SECRET_ACCESS_KEY="секрет"
chmod 600 /opt/restic.env
RESTIC_PASSWORD— ключ шифрования репозитория. Без него данные не восстановить никогда и никому, включая вас. Сохраните его отдельно от сервера: в менеджере паролей, а не только в этом файле.
Инициализация хранилища — один раз:
source /opt/restic.env
restic init
Дальше бэкап выполняется одной командой:
restic backup /opt/backups /var/www
Ротация — хранить последние 7 ежедневных, 4 еженедельных и 6 ежемесячных копий:
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
Обе команды добавляем в расписание:
crontab -e
0 5 * * * . /opt/restic.env && restic backup /opt/backups /var/www >> /var/log/restic.log 2>&1
0 6 * * 0 . /opt/restic.env && restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune >> /var/log/restic.log 2>&1
Первая строка — ежедневная копия, вторая — еженедельная чистка старых.
Посмотреть список копий:
restic snapshots
Главное: проверить восстановление
Бэкап, который ни разу не разворачивали, бэкапом не является. Самые частые сюрпризы обнаруживаются именно при первой попытке восстановиться: дамп оказался пустым, в архив не попала папка с загрузками, пароль от шифрования утерян.
Проверку делают раз в пару месяцев. Достаньте один файл:
restic restore latest --target /tmp/test --include /var/www/site/index.php
И проверьте, что дамп базы не битый:
gunzip -t /opt/backups/db-2026-09-25.sql.gz && echo "архив целый"
zcat /opt/backups/db-2026-09-25.sql.gz | head -30
В начале дампа должны идти команды CREATE TABLE, а не пустота и не текст ошибки.
Полноценная проверка — развернуть копию на тестовом сервере. Тариф «Старт» за 5 € в месяц стоит дешевле любого простоя, а такая репетиция снимает главный вопрос: «а точно ли мы сможем восстановиться?»
Как восстанавливаться
Один файл из локального архива:
tar -xzf /opt/backups/www-2026-09-25.tar.gz -C /tmp var/www/site/index.php
Базу целиком:
zcat /opt/backups/db-2026-09-25.sql.gz | mysql -u root -p
Всё из внешнего хранилища:
source /opt/restic.env
restic restore latest --target /
Сервер целиком после потери: заказываете новый VPS, ставите restic, подключаетесь к тому же репозиторию с тем же паролем, восстанавливаете данные, разворачиваете конфиги из архива config-*.tar.gz. Порядок действий по подъёму окружения тот же, что при переезде: Как перенести сайт без простоя.
Сколько копий хранить
Схема, закрывающая большинство ситуаций:
- 7 ежедневных — на случай «вчера всё работало»
- 4 еженедельных — ошибка обнаружилась через пару недель
- 6 ежемесячных — испорченные данные заметили нескоро
Занимают такие копии немного: restic хранит только изменения между снимками, а не полный архив каждый раз.
Частые вопросы
Сколько места нужно под бэкапы? Ориентируйтесь на двукратный объём данных для локальных копий с недельным хранением. Во внешнем хранилище — примерно полтора объёма, благодаря дедупликации.
Нагружают ли бэкапы сервер?
Сжатие архива даёт кратковременную нагрузку на процессор. Поэтому расписание ставят на ночь, а для mysqldump используют --single-transaction — тогда сайт продолжает работать во время выгрузки.
Можно ли хранить копии на том же сервере? Как единственный вариант — нет. Они не спасут при потере сервера, а при взломе злоумышленник удалит их первым делом. Локальные копии годятся только для быстрого отката, внешние — для настоящей страховки.
Что если база очень большая?
Свыше нескольких десятков гигабайт mysqldump становится медленным. Тогда смотрят в сторону xtrabackup или физической репликации на второй сервер.
Как бэкапить контейнеры Docker?
Нужны только тома с данными и файлы docker-compose.yml, образы скачиваются заново. Подробнее: Docker на VPS.
Нужны ли бэкапы, если есть снапшоты? Это разные инструменты. Снапшот — быстрый откат всего сервера. Бэкап — доступ к отдельным файлам, история изменений и копия вне площадки. Хорошая схема использует и то, и другое.
Итог
Минимум, который должен быть на любом боевом сервере: ночной скрипт с ротацией, выгрузка во внешнее хранилище и уведомление о том, что бэкап не выполнился.
Настройка — те самые десять минут. Проверка восстановления — ещё полчаса раз в пару месяцев. Это единственное, что отличает «у нас есть бэкапы» от «мы смогли восстановиться».
Перед любым рискованным изменением не забывайте про базовую защиту самого сервера: 7 шагов безопасности.

