Чистый Compose env и Caddy recreate при rollback¶
- Дата: 2026-08-26.
- Статус: VALIDATED.
- Тип задачи: DEV/STAGE deploy и rollback.
- Компоненты: Docker images, Docker Compose, Caddy edge, runtime env, migration job.
- Теги: deploy, rollback, compose, environment, entrypoint, migration, caddy, admin-off.
- Связанные решения: 0025, 0026.
- Связанный Skill: отсутствует.
Контекст и границы¶
Во время отката DEV deploy shell ранее загрузил Resend variables через set -a.
Восстановленный .env содержал Gmail, но exported shell variables имели приоритет
над docker compose --env-file, поэтому старый image получил provider resend и
остался unhealthy. Одновременно edge Caddy имел admin off, поэтому команда
caddy reload не могла обратиться к admin API.
При STAGE rollback 2026-08-26 прежние image IDs сначала были запущены с новым
Compose. Старый server image содержал прежний API entrypoint и не содержал нового
migration entrypoint, поэтому пара old image + new Compose получила
MODULE_NOT_FOUND, хотя база и сами images были исправны.
Запись описывает только наблюдённые runtime-механизмы. Она не является активным deploy Skill, не разрешает server mutation и не заменяет task-specific rollback.
Что сработало¶
- Выполнять rollback Compose в новом чистом SSH/process environment либо явно
unsetcandidate variables до чтения восстановленного.env. - При
admin offприменять проверенный Caddyfile через controlled container recreate, а не через admin API reload. - В rollback trap отключать fail-fast на время recovery и независимо пытаться восстановить edge и DEV, сохраняя exit status каждого шага.
- После recovery проверять runtime provider/image, readiness, оба внешних домена и сохранность logical dump; volumes и backups не удалять.
- Сохранять и восстанавливать как один recovery set точные
image refs/IDs,.envиcompose.yml; до mutation проверять, что команды/entrypoints сохранённого Compose существуют в восстанавливаемых images. - Если новый Compose добавил одноразовый migrator, использовать сохранённый старый Compose, не выполнять schema downgrade и оставлять постоянный volume нетронутым.
Что не сработало и почему¶
docker compose --env-file old.envв shell с exported candidate variables не гарантирует old runtime config: process environment имеет более высокий приоритет.caddy reloadнесовместим с фактическимadmin off.- Первый rollback trap работал под
set -eи остановился на unhealthy DEV раньше, чем восстановил edge-файл. - Возврат только old images и env под текущим Compose: API ушёл в restart loop из-за
нового entrypoint, а migrator завершился
1, потому что файла запуска не было в old image.
Проверки и свидетельства¶
- Первый recovery из чистого SSH process вернул прежние DEV images/Gmail и
readiness
200. - Общий edge был восстановлен через recreate; DEV и legacy STAGE снова возвращали
прежний
strict-origin-when-cross-origin. - STAGE images, start times, volumes и data runtime не изменились; актуальный
pre-deploy DEV dump повторно прошёл
pg_restore --list. - Полный evidence: task card и session log (session log excluded from published snapshot).
- STAGE recovery подтвердил точную связку old images/env/Compose: API/web вернулись
в healthy, restart counters —
0, DEV и edge/docs не изменились; затем тот же exact candidate был безопасно redeployed с новым dump и rollback package. Evidence: STAGE task card.
Когда применять¶
- при rollback Compose после загрузки candidate secrets в shell;
- при изменении Compose commands, entrypoint paths или добавлении migration service;
- при Caddy runtime с отключённым admin API;
- при общем ingress, где recovery должен проверить несколько доменов.
Когда не применять¶
- как универсальную команду deploy без сверки фактического Compose/Caddy runtime;
- для удаления volumes, backups, releases или images;
- как доказательство успешного нового deploy.
Следующее улучшение¶
Recovery-set contract независимо проверен после фактического DEV/STAGE опыта. Критический deploy Skill пока не создаётся: общий end-to-end контракт ещё не стабилизирован и не должен активироваться из одной memory record.