MAATRIX / Блог / Чек-лист перед крупным релизом: что проверить на сервере за час до выкатки

Чек-лист перед крупным релизом: что проверить на сервере за час до выкатки

MAATRIX

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

Почему часовое окно, а не общий регламент

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

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

Ключевое отличие часового окна в том, что оно происходит настолько близко к моменту выкатки, что между проверкой и релизом почти нет зазора для изменения ситуации. Если вы проверили свободное место на диске утром, а релиз в 18:00, за это время логи, временные файлы сборки или чужой процесс могут съесть заметную часть места — и вы узнаете об этом уже после того, как миграция базы упадёт с ошибкой записи. Час — разумный компромисс: достаточно близко к событию, чтобы данные были актуальны, и достаточно заранее, чтобы успеть среагировать, если что-то не так.

Бэкап: свежий, а не «вчерашний по расписанию»

Плановый ночной бэкап — это не то же самое, что бэкап непосредственно перед релизом. Если релиз в 15:00, а последний снапшот был в 3:00 ночи, откат в случае проблемы отбросит вас на 12 часов данных назад — это может означать потерянные заказы, платежи, регистрации пользователей. Перед крупным релизом делайте отдельный бэкап, привязанный к моменту, а не полагайтесь на плановый.

Что проверить конкретно:

  • Бэкап базы данных снят после последней транзакции перед стопом трафика, а не по вчерашнему расписанию.
  • Бэкап проверяем — не просто файл существует, а он не битый и открывается. Для PostgreSQL это можно проверить командой:
pg_restore --list backup_pre_release.dump > /dev/null && echo "OK: бэкап читается"
  • Для MySQL/MariaDB имеет смысл хотя бы проверить, что дамп не оборвался на середине:
tail -c 200 backup_pre_release.sql | grep -q "UNLOCK TABLES" && echo "OK: дамп завершён корректно"
  • Бэкап физически лежит не только на этом сервере — если релиз повредит диск или файловую систему, локальная копия бесполезна. Хотя бы rsync или облачное хранилище в дополнение к локальному снапшоту.
  • Время выполнения бэкапа известно заранее — если полный дамп базы занимает 40 минут, а у вас часовое окно, начинайте бэкап не «за час», а раньше, оставляя время на саму проверку.
  • Если используется LVM или ZFS — снапшот тома снят непосредственно перед миграцией, а не после того, как приложение уже начало писать новые данные.

Если в компании уже настроен процесс бэкапов через BorgBackup, Percona XtraBackup или встроенные снапшоты облака — под крупный релиз это не отменяет отдельной ручной или скриптовой проверки: штатный бэкап рассчитан на восстановление после сбоя «в среднем», а не конкретно на откат этого релиза.

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

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

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

План отката: подготовлен и протестирован, а не только описан

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

Проверка за час до релиза должна ответить на конкретные вопросы:

  • Команда или скрипт отката существует в виде исполняемого артефакта (скрипт, playbook, кнопка в CI), а не абзаца текста в вики.
  • Откат был протестирован хотя бы на стейджинге в последнюю неделю — а не полгода назад, когда схема базы была другой.
  • Предыдущая версия приложения (образ, артефакт сборки) физически доступна и не удалена ретеншеном registry:
docker images | grep myapp | head -5
  • Если релиз включает миграцию базы — миграция обратима или explicitly необратима, и это осознанное решение, а не забытая деталь. Необратимые миграции (удаление колонки, смена типа данных с потерей точности) лучше разносить на отдельный релиз после того, как новая версия кода отработала стабильно.
  • Известно точное время, за которое откат выполняется целиком, и это время меньше, чем допустимое окно простоя по договорённостям с пользователями.
  • Ответственный за запуск отката назван поимённо, а не «кто-нибудь из дежурных» — в стрессовой ситуации распределение ответственности «по умолчанию» приводит к задержке в решающие минуты.

Подробный разбор того, как готовить план отката отдельно от плана миграции, — в статье план отката миграции. Если хочется понять, как выглядит ситуация, когда отката не подготовили заранее, полезно почитать как откатиться, если обновление положило прод.

Место на диске и ресурсы под пиковую нагрузку деплоя

Деплой сам по себе — это нагрузка: сборка Docker-образов, распаковка архивов, запись логов миграции, временные файлы CI-раннера, дублирование данных при blue-green выкатке. Сервер, который спокойно работает под обычной нагрузкой, может не выдержать именно момент релиза — и упасть не из-за бага в коде, а из-за того, что закончилось место на диске в середине миграции базы.

Что проверить за час:

df -h

Смотрите не только на корневой раздел, но и на разделы под Docker (/var/lib/docker), под логи (/var/log) и под данные СУБД, если они на отдельном томе. Правило разумного запаса: если пиковый прирост данных за релиз (новый образ + старый образ + бэкап + логи миграции) может занять условно 5 ГБ, свободного места должно быть заметно больше — с запасом на непредвиденное, а не впритык.

docker system df

Покажет, сколько места съедено неиспользуемыми образами и слоями — часто оказывается, что «нет места» решается одной командой docker image prune -a после согласования, что старые образы точно не понадобятся.

Дополнительно проверьте:

  • Оперативную память и текущую нагрузку (free -h, htop или uptime) — сборка и параллельный прогон миграций поверх обычного трафика может создать пик, которого не было на тестах.
  • Лимиты открытых файлов и соединений, если релиз перезапускает пул воркеров или увеличивает число процессов (ulimit -n, конфиг nproc в systemd-юните).
  • Очередь фоновых задач (Celery, Sidekiq, cron) — если перед релизом накопился большой бэклог, деплой может конкурировать с ним за CPU и I/O.
  • Достаточно ресурсов, если планируется параллельный запуск старой и новой версии (canary или blue-green) — на это временно нужно в полтора-два раза больше CPU/RAM, чем в обычном режиме.

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

Все причастные на связи: явное подтверждение, а не предположение

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

За час до выкатки имеет смысл получить явное подтверждение, а не рассчитывать на молчаливое согласие:

  • Кто выполняет деплой — назван поимённо.
  • Кто отвечает за базу данных, если релиз включает миграцию — на связи и в курсе точного времени.
  • Кто отвечает за инфраструктуру (сеть, балансировщик, DNS), если релиз меняет топологию — предупреждён.
  • Кто принимает решение об откате и по каким критериям — не «мы решим по ситуации», а конкретный порог (например, error rate выше X% в течение Y минут).
  • Канал связи для инцидента определён заранее (отдельный чат, конференц-звонок) — не тот же чат, где параллельно идёт непрофильное обсуждение.

Практический приём — короткое сообщение в общий канал команды за 15-20 минут до старта: «Начинаем релиз X в 18:00, ожидаемое окно Y минут, ответственный за откат — Иван, критерий отката — рост 5xx выше 2% на 3 минуты». Это занимает минуту, но переводит неявные договорённости в явные и фиксирует момент, с которого отсчитывается ответственность.

Мониторинг настроен для отслеживания метрик сразу после релиза

Мониторинг, который в целом работает, — не то же самое, что мониторинг, настроенный именно под этот релиз. Общие дашборды показывают усреднённые метрики за часы или дни, а сразу после выкатки нужна возможность увидеть аномалию за секунды и минуты, пока она не превратилась в заметный простой.

Проверьте перед стартом:

  • Дашборд с ключевыми метриками (error rate, latency, RPS, использование CPU/RAM) открыт и обновляется в реальном времени, а не раз в 5 минут по умолчанию.
  • Алерты на критичные пороги активны, а не временно отключены после прошлого инцидента с ложным срабатыванием — такое забывают включить обратно.
  • Логи приложения доступны для просмотра в реальном времени (journalctl -u myapp -f, или дашборд в Grafana Loki/ELK), а не только пишутся в файл, который никто не откроет, пока не пожалуется пользователь.
  • Отдельно отслеживается метрика, специфичная именно для этого релиза — если релиз меняет логику оплаты, смотрим не только на общий error rate, а на конкретно success rate платежей.
  • Определено время наблюдения после релиза — не «задеплоили и разошлись», а конкретные 30-60 минут повышенного внимания, в течение которых ответственный не переключается на другие задачи.

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

Коммуникация с пользователями, если ожидается простой

Если релиз предполагает даже короткое окно недоступности — техническое обслуживание, миграцию базы с блокировкой таблиц, переключение DNS — молчаливый простой воспринимается пользователями хуже, чем предупреждённый. Человек, который видит страницу техобслуживания с объяснением, реагирует спокойнее, чем тот, кто просто получает ошибку 502 без объяснений.

Что стоит сделать заранее, но проверить именно за час до старта:

  • Страница технического обслуживания (maintenance page) готова и включается одной командой или флагом — не пишется на ходу в момент простоя.
  • Уведомление пользователям отправлено заранее (email, баннер в интерфейсе, статус-страница), если простой плановый и известен заранее.
  • Статус-страница сервиса (если она есть) обновлена или готова к обновлению одним кликом.
  • Служба поддержки в курсе окна и ожидаемого поведения системы — чтобы отвечать пользователям консистентно, а не «сейчас узнаем».
  • Если простой не планировался, но релиз рискованный — заготовлен шаблон сообщения на случай, если он всё же понадобится, чтобы не писать текст в момент, когда уже нужно действовать.

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

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

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

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

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

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

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

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

Можно, но тогда регламент станет длинным документом, который реже перечитывают целиком. Практичнее держать общий регламент компактным (роли, процесс, требования к ревью), а короткий часовой чек-лист — отдельным быстрым списком, который реально прогоняют перед каждым крупным релизом, потому что он занимает 10-15 минут, а не полчаса чтения документа.

Нужен ли такой чек-лист для каждого мелкого релиза, например для правки одной строчки в конфиге?

Нет, для мелких изменений с низким риском это избыточно и со временем чек-лист начнут игнорировать. Разумный подход — определить заранее критерии «крупного» релиза (миграция базы, изменение схемы API, релиз в пиковые часы, изменения в биллинге) и применять полный чек-лист именно к ним.

Что делать, если за час до релиза чек-лист выявил проблему, например бэкап не прошёл?

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

Как автоматизировать часовой чек-лист, чтобы не проверять всё руками каждый раз?

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

Что если релиз выкатывается автоматически по CI/CD без ручного деплоя?

Часовое окно проверки актуально и здесь — просто часть пунктов переносится в автоматические gate-проверки перед стадией деплоя (проверка бэкапа, свободного места, статуса предыдущего деплоя), а часть (подтверждение готовности команды) остаётся ручным шагом одобрения перед тем, как пайплайн продолжит выполнение.

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

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

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