⏪ Откат (rollback)

Что делать, если деплой сломал прод. Приоритет - вернуть рабочее состояние быстро, разбор причины - потом. Инциденты фиксировать в capital-support.

Уровни отката (по возрастанию радиуса)

Уровень Когда Действие
1. Код новый билд падает/баг в UI вернуть предыдущий коммит + пересобрать
2. Данные миграция/операция испортила данные PITR / restore из бэкапа
3. Целиком сервер недоступен DR на новый сервер (см. §DR)

1. Откат кода

Быстрее всего - откатить рабочее дерево на прошлый коммит головного capital и пересобрать:

# на capital-prod:
cd ~/capital && git log --oneline -5      # если репо есть на сервере; иначе rsync прошлой версии с dev
docker compose up -d --build              # после возврата кода

Если деплой был через rsync (не git на сервере) - re-rsync предыдущего состояния дерева с dev-машины (git checkout <prev> -- . локально → rsync → build → up).

⚠️ Если релиз включал миграцию - откат кода НЕ откатывает схему. Сначала оцени: новая схема обратно-совместима со старым кодом? Если да - можно откатить только код. Если нет - нужен откат данных (§2) или forward-fix миграцией.

Целевое состояние (GHCR): rollback = docker compose pull предыдущего тега образа (храним 5 последних) - секунды.

2. Откат данных (PITR / restore)

Перед рискованной миграцией/деплоем - внеочередной бэкап (~/bin/capital-backup.sh) и запись LSN, чтобы можно было PITR ровно к моменту «до».

3. DR (полная потеря сервера)

Быстрый DR ≤ 2-4 ч (HA-кластера нет - сознательно). Ранбук: 1. Заказать новый сервер (Hetzner API), hardening с первого часа. 2. Restore БД из B2 (или age-бэкапа) - deploy/pgbackrest/README.md §Restore. ⚠️ Восстанавливать в точное имя volume, которое ждёт compose (<project>_capital_db, на текущем проде capital_capital_db; authoritative - /root/pgbackrest/RESTORE-NOTES.txt). Restore в неверное имя тихо игнорится, и compose поднимет ПУСТУЮ БД. 3. Deploy образов (GHCR - целевое) / rsync + build. 4. Перевести Cloudflare tunnel на новый сервер. 5. Смоук: login-страницы обоих приложений рендерятся, select count(*) from companies.

Прецедент: переезд team-nextcloud → capital-prod 15.09.2026 был по сути первым DR-тестом (restore из age-бэкапа, 32 таблицы, ~1 мин простоя на переключении tunnel).

Мгновенный rollback после переезда

Старый стек на team-nextcloud остановлен, но не удалён (~/capital) - при остром регрессе можно вернуть его как мгновенный rollback (удалить после недели стабильности нового прода).

После отката