MAATRIX / Блог / Миф: бэкапить нужно только базу данных

Миф: бэкапить нужно только базу данных

MAATRIX

Диск на сервере умирает, или хостер теряет том, или кто-то по ошибке накатывает rm -rf не туда — и первая реакция обычно спокойная: «у нас есть бэкап базы, восстановим». Через час выясняется, что база действительно восстановилась, а сервис всё равно не работает: нет nginx-конфига, нет загруженных пользователями файлов, нет SSL-сертификата, никто не помнит, что там было в cron. Бэкап данных — это не то же самое, что бэкап работоспособности сервиса, и разница между ними обычно всплывает в худший момент.

Почему миф живёт: база данных кажется единственной «настоящей» ценностью

Логика понятна: в базе — заказы, пользователи, платежи, контент. Всё остальное выглядит второстепенным — «конфиг я и заново напишу», «код у меня и так на компьютере», «сертификат перевыпущу за минуту». По отдельности каждое из этих допущений звучит разумно. Проблема в том, что при реальной аварии их приходится закрывать одновременно, под давлением времени, и часто выясняется, что «заново напишу» означает часы или дни, а не минуты.

Второй источник мифа — путаница между *данными* и *сервисом*. Бэкап базы спасает данные. Но пользователь, зайдя на сайт после восстановления, ждёт не данные — он ждёт работающий сервис: с тем же дизайном, теми же картинками в товарах, тем же адресом по HTTPS без предупреждения браузера. Разрыв между «данные восстановлены» и «сервис работает» — это как раз тот набор компонентов, который обычно не бэкапят.

Похожая иллюзия разбирается и в статье про RAID как замену бэкапу: избыточность на уровне диска тоже создаёт ложное чувство защищённости, хотя решает другую задачу. С облачными провайдерами то же самое — механизм разбирает материал про миф «облако само делает бэкапы».

Что теряют вместе с БД, если бэкапят только её

Вот типичный список того, что упускают при инвентаризации бэкапов, и что происходит с сервисом при потере каждого пункта.

КомпонентЧто произойдёт при потереНасколько быстро заметят
Конфиги сервисов (nginx, systemd, php-fpm, docker-compose)Сайт не поднимется даже с восстановленной БД и кодом — нет маршрутизации, портов, лимитовСразу, при первой попытке запуска
Загруженные пользователями файлы (медиа, вложения, аватары)Записи в БД есть, а файлов по ссылкам нет — битые картинки, пустые вложенияВ течение первых часов, по жалобам пользователей
Код приложения (если не в git)Сервис физически нечем запускатьСразу
SSL-сертификаты и приватные ключиHTTPS падает на «небезопасное соединение», часть клиентов и ботов отваливаетсяСразу, критично для SEO и доверия
Cron-задачи и systemd-таймерыФоновые задачи (рассылки, очистка, синхронизация) молча перестают выполнятьсяЧерез дни или недели — сложнее всего заметить
Кастомные настройки сервисов (firewall, лимиты, переменные окружения)Сервис поднимается, но ведёт себя иначе: другие таймауты, открытые порты, отсутствующие ключи APIПостепенно, по мере наступления edge-кейсов

Обратите внимание на последнюю колонку: часть потерь заметна сразу, а часть — только спустя время, когда уже поздно проверять, было ли в бэкапе то, что нужно.

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

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Конфигурация сервисов: маленькие файлы с непропорциональными последствиями

Конфиги — это то, что чаще всего живёт только на одном сервере и нигде больше. Типичный набор для веб-сервиса на VPS:

/etc/nginx/sites-available/
/etc/nginx/nginx.conf
/etc/systemd/system/*.service
/etc/php/8.3/fpm/pool.d/
/etc/redis/redis.conf
/etc/postgresql/16/main/postgresql.conf
/etc/postgresql/16/main/pg_hba.conf
/etc/cron.d/
/etc/environment
docker-compose.yml + .env

Каждый из этих файлов может быть результатом многих часов настройки: подобранные таймауты, rate-limit под конкретную нагрузку, правила location для API и статики, лимиты по памяти для PHP-FPM пулов под конкретный трафик. Восстановить БД и код — не значит восстановить эти решения. Придётся либо вспоминать их по памяти (реально — не вспомнить), либо настраивать заново методом проб и ошибок, теряя на это часы, пока сервис работает нестабильно или не работает вовсе.

Практическое решение — держать /etc (или хотя бы релевантные подкаталоги) под версионным контролем или в отдельном архиве, синхронизируемом с тем же расписанием, что и бэкап БД:

tar -czf /backup/etc-$(date +%F).tar.gz \
  /etc/nginx /etc/systemd/system /etc/php \
  /etc/cron.d /etc/postgresql /etc/environment

# ротация — оставляем 14 последних архивов
find /backup -name 'etc-*.tar.gz' -mtime +14 -delete

Если конфигов много и они меняются часто, разумнее завести для /etc git-репозиторий (например, через etckeeper) — тогда бэкап получает историю изменений, а не только последний снимок.

Файлы, загруженные пользователями: почему это отдельная категория

Медиатека, вложения к тикетам, аватары, PDF-счета, файлы в объектном хранилище приложения — всё это физически не находится в базе данных, даже если ссылки на них там есть. Типичная ошибка — настроить pg_dump или mysqldump по расписанию и решить, что бэкап готов, забыв про /var/www/app/storage/uploads или примонтированный диск с медиа.

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

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

rsync -a --delete /var/www/app/storage/uploads/ /backup/uploads/
# или, если бэкап идёт во внешнее хранилище:
rclone sync /var/www/app/storage/uploads/ remote:backups/uploads/

Полный разбор того, что значит забэкапить сервис целиком, а не только его данные, — в статье «Бэкап всего сервера целиком».

Код без git, сертификаты и cron — три источника тихих сюрпризов

Код приложения, если он не в git. Звучит как редкость в 2026 году, но на практике встречается регулярно: быстрые правки прямо на проде «на скорую руку», кастомные патчи в vendor-директориях, локальные конфиги окружения, которые никогда не коммитили из соображений безопасности. Если единственная копия кода — на диске сервера, а диск потерян, восстановление БД ничего не решает: разворачивать нечего. Минимальная защита — гарантировать, что боевая ветка действительно запушена в удалённый репозиторий, и отдельно бэкапить любые файлы, которые сознательно исключены из git (.env, локальные патчи, самописные скрипты обслуживания).

SSL-сертификаты и приватные ключи. Если сертификаты выпущены через Let's Encrypt и автообновляются certbot, формально их можно перевыпустить заново — но для этого нужен рабочий DNS, доступный порт 80/443 и время на прохождение validation, что при аварии — далеко не «пять минут». Если же используются платные сертификаты с ручной установкой или клиентские сертификаты для внутренних сервисов, их повторный выпуск может занять дни и требовать участия сторонней стороны. Каталоги /etc/letsencrypt/ и любые кастомные *.pem/*.key должны попадать в бэкап конфигурации.

Cron-задачи и systemd-таймеры. Это самая коварная категория, потому что её отсутствие не ломает сервис визуально. Сайт открывается, форма отправляется, всё выглядит нормально — а фоновая задача, которая должна была раз в сутки чистить временные файлы, отправлять email-дайджест или синхронизировать остатки на складе, просто не существует после восстановления. Замечают это не сразу: диск постепенно заполняется, письма перестают уходить, склад расходится с реальностью — и связать это с недавним восстановлением сервера догадываются далеко не сразу. crontab -l для каждого пользователя и содержимое /etc/cron.d/, /etc/systemd/system/*.timer стоит включать в тот же архив, что и остальные конфиги.

Как составить полную инвентаризацию для реального восстановления

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

КомпонентГде физически хранитсяКак бэкапится сейчасКак восстанавливается
База данных/var/lib/postgresqlpg_dump по cron, ежедневноpg_restore из дампа
Код приложения/var/www/appgit-репозиторий (удалённый)git clone + git checkout
Конфиги сервисов/etc/*— (пробел)
Пользовательские файлы/var/www/app/storage— (пробел)
SSL-сертификаты/etc/letsencrypt— (пробел)
Cron/таймеры/etc/cron.d, systemd— (пробел)
Переменные окружения / секреты.env, менеджер секретов— (пробел)

Пробелы в третьей и четвёртой колонках — это и есть реальная зона риска: не абстрактная «недостаточность бэкапов», а конкретные незакрытые точки. После заполнения таблицы для своего проекта список пробелов обычно короче, чем кажется на старте — часто это два-три пункта (чаще всего конфиги и cron), которые можно закрыть одним дополнительным скриптом на 15-20 строк.

Отдельный вопрос — согласованность бэкапов по времени. Если БД бэкапится в 3:00, а конфиги — вручную раз в месяц, при восстановлении можно получить рассинхронизацию: свежие данные с устаревшей структурой сервиса (изменившиеся с тех пор nginx-правила, добавленные переменные окружения). Разумный минимум — синхронизировать расписание бэкапа конфигов, кода (если не в git) и пользовательских файлов с расписанием бэкапа БД, даже если конфиги меняются редко: лишний идентичный архив стоит дёшево, а рассинхронизация при восстановлении стоит дорого.

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

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

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Если у меня Docker-контейнеры, разве не достаточно бэкапить volume с БД?

Нет — сам docker-compose.yml, .env с переменными, кастомные Dockerfile и примонтированные volume с загрузками — это отдельные компоненты, без которых docker compose up либо не запустится, либо запустится не с той конфигурацией.

Стоит ли бэкапить весь /etc целиком или выбирать конкретные файлы?

Для небольшого сервера обычно проще бэкапить весь /etc — это несколько мегабайт, а не гигабайты, и экономия места не стоит риска забыть один нужный файл. Для крупных инсталляций с сотнями сервисов имеет смысл явно перечислить релевантные каталоги.

Можно ли просто раз в квартал делать полный снапшот диска и не думать об отдельных компонентах?

Снапшот диска действительно закрывает проблему «забыли что-то бэкапнуть», но у него свои ограничения: большой размер, зависимость от гипервизора, невозможность восстановить один файл без разворачивания всего образа. Разумная практика — сочетать снапшоты образа с раздельными бэкапами БД и файлов для более гибкого и быстрого восстановления в частых сценариях.

Как понять, что инвентаризация точно полная?

Единственный надёжный способ — тестовое восстановление на чистом сервере по своим же бэкапам, без ручных доработок «руками». Если сервис поднялся и работает так же, как на проде, — список полный. Если пришлось что-то донастраивать вручную — этот пункт и был пропущен в бэкапе.

Что делать, если ресурсов на всё это не хватает — какие компоненты бэкапить в первую очередь?

Приоритет: БД → код (если не в git) и конфиги → пользовательские файлы → сертификаты и cron. Первые два блока определяют, поднимется ли сервис вообще; остальные влияют на то, будет ли он работать корректно и незаметно для пользователя.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →