Журнал Tenku

Бэкапы VPS: копии, которые реально восстанавливаются

Бэкап — это не файл backup.zip на том же NVMe. Бэкап — это проверенное восстановление на другой машине в понятный срок. Пока вы не поднимали копию, у вас архив неизвестного качества. Диск умирает вместе с «ежедневным бэкапом» в /var/backups на нём же.

Tenku даёт вам машину и панель. Схему копий выбираете вы: так устроен универсальный VPS, не конструктор с одной кнопкой «спасти всё». Ниже — минимум, который спасает магазины и CRM, без корпоративного софта на полмиллиона.

Что копировать обязательно

Для типичного сайта:

  • файлы приложения и загрузок (/var/www/..., особенно uploads);
  • конфиги Nginx, PHP, systemd, crontab;
  • секреты: .env, wp-config.php — в защищенное место, не в публичный S3 без шифрования;
  • дамп базы, согласованный (--single-transaction для InnoDB).

Можно не таскать ежедневно:

  • /usr, /var/cache/apt — ставится пакетами;
  • ядро и весь корневой диск целиком, если вы не умеете такое восстанавливать и не тестировали;
  • node_modules и сборки — если собираете из git.

«Снимок всего диска раз в месяц и надежда» лучше, чем ничего, хуже, чем ночной дамп базы плюс rsync uploads. База за вчера и файлы за сегодня часто дают поломанные товары. Копируйте согласованно: сначала дамп, сразу файлы, одним окном.

Правило 3-2-1 без плаката на стене

  • 3 копии данных (прод + ещё две).
  • 2 разных носителя (диск VPS не считается двумя, даже если две папки).
  • 1 копия вне площадки (другой провайдер, object storage, домашний NAS с шифрованием, второй VPS в другой локации).

Практически для малого проекта: ночной архив на второй VPS или в S3-совместимое хранилище + еженедельная копия на ПК в сейфе не нужна, если object storage уже в другом ДЦ. Главное — не тот же диск.

База: mysqldump, который не врёт

mkdir -p /root/backups
mysqldump -u wp -p --single-transaction --quick --routines --triggers wp | gzip > /root/backups/wp-$(date +%F).sql.gz

--lock-tables на MyISAM может стопорить сайт. InnoDB + --single-transaction — правильный путь.

Проверка дампа не «файл не нулевой»:

gzip -t /root/backups/wp-2026-09-16.sql.gz
zcat /root/backups/wp-2026-09-16.sql.gz | tail

Должен быть конец дампа, не обрыв на половине таблицы. Обрыв — типичный диск кончился во время gzip.

Хранение только в /root/backups на этом же VPS — этап 1. Этап 2 — rsync или rclone на вторую точку сразу в cron.

Файлы: rsync, не семь слоёв zip в GUI

rsync -aH --delete /var/www/wp/ /mnt/backup/wp-files/

--delete на приёмнике зеркала делает его похожим на прод. Не используйте --delete в первую ночь, пока не убедились, что путь приёмника верный. Иначе сотрёте единственную копию.

Исключите кэш:

rsync -aH --delete --exclude 'wp-content/cache/' /var/www/wp/ backup:/data/wp/

Симлинки, права, владельцы: -a это закрывает. Архив zip с FTP часто теряет владельца и ломает восстановление WP.

Cron, который напишет вам, если упал

#!/bin/bash
set -euo pipefail
STAMP=$(date +%F)
mysqldump -u wp -pСЕКРЕТ --single-transaction wp | gzip > /root/backups/wp-$STAMP.sql.gz
rclone copy /root/backups/wp-$STAMP.sql.gz remote:db/
rclone sync /var/www/wp/uploads remote:uploads/
find /root/backups -mtime +14 -delete

Пароль в crontab виден ps — лучше ~/.my.cnf с chmod 600. Письмо себе в конце скрипта (mail или webhook) при ненулевом коде. Молчаливый cron 90 дней — сюрприз в день аварии.

Не храните 365 ежедневных дампов на 20 ГБ диск. 7 ежедневных + 4 недельных достаточно большинству. Юридические сроки хранения — отдельно, не на системном диске прома.

Как проверять восстановление

Раз в месяц:

  1. Новый каталог или дешёвый второй VPS / локальная VM.
  2. Поднимаете Nginx+PHP+БД минимально.
  3. Импорт вчерашнего дампа, rsync uploads.
  4. Логин в админку, открытие карточки товара, картинка на месте.

Время, которое ушло — ваш RTO. Если вы не уложились в ночь — схема сложная, упростите. Если картинок нет — копировали не тот каталог.

Восстановление «на тот же сервер поверх живого прода» репетируйте осторожно: легко уничтожить прод, думая, что это песочница.

Что делать в день аварии

Диск заполнен — сначала место, бэкап уже не снять. OOM — сначала стабилизировать, потом думать о копиях.

Диски гипервизора — редкость, но для этого и нужна копия вне ноды. Тикет в Tenku: « please помогите поднять из вашего снимка», если снимок есть в вашей схеме. Если вы его не делали и копий нет — честно: данные за временем последнего выноса.

После взлома не восстанавливайте /var/www как есть: туда мог попасть shell. Код из git + дамп БД + uploads, просмотренные на вирусы хотя бы поиском <?php в jpg. См. безопасность.

Ошибки, которые делают бэкап фикцией

  • Архив рядом с public_html, доступный по URL /backup.zip.
  • Один и тот же пароль БД в открытом виде в трёх скриптах в git.
  • Дамп без routines, а в проде триггеры.
  • Копия только файлов WP без базы и наоборот.
  • Шифрование «потом». На чужом S3 без шифрования лежат персональные данные клиентов.
  • Первый бэкап в день запуска магазина, второй не настроен.

Минимальный старт сегодня вечером

  1. mysqldump на диск VPS + проверка gzip -t.
  2. rclone или второй сервер — вынести дамп.
  3. rsync uploads.
  4. Запись в календарь: через 7 дней учебное восстановление на поддомене.

Пока эти четыре пункта не сделаны, разговор про «надёжный VPS» пустой. Надёжность — свойство системы с копией, не шильдик тарифа. Когда копии есть — можно спокойно обновлять PHP и тему. Когда нет — любой apt full-upgrade кажется страшным, и вы живёте на вечно уязвимом стеке.

Нужен сервер под задачу?

Выберите тариф и локацию — VPS появится в кабинете.

Смотреть тарифы