Учебник веб-разработки
Разделы учебника
На этой странице

XI. DevOps

Релизные ветки и blue-green

Первый production выпуск v0.1.0 выполнен через SourceCraft 7 октября 2026 года: четыре приложения работают на blue, staging охлаждён. Свидетельства и границы проверки находятся в отчёте приёмки.

main обновляет test. release/X.Y даёт полный staging и receipt с точными SHA, четырьмя digest и generation. Stable native Release vX.Y.Z должен ссылаться на эту же текущую ветку, capsule и receipt. Draft/RC не продвигаются.

Два цвета приложений

Compose-проекты gheilt-production-blue и gheilt-production-green содержат web, CMS, Storybook и docs; PostgreSQL/Garage/uploads общие и остаются прежними. У каждого цвета своя сеть и уникальные имена контейнеров. Web обращается к gheilt-COLOR-cms, чтобы общий backend не разрешил имя CMS другого цвета. В этих проектах нет build, host ports и Docker socket.

Под deploy.lock сначала проверяются свежий авторитет, CMS contract и private backup с restore drill. Candidate получает готовые digest; затем проходит внутренние проверки и обновление кеша. Caddy меняет четыре upstream одним reload. Media и остальные стенды остаются в конфигурации. X-App-Release проверяется у самого web; диагностический X-Production-Release показывает тег выпуска. Только после публичной проверки записывается active receipt и останавливается предыдущий цвет. Production не охлаждается.

Прерывание и откат

production/intent.json сохраняет прежние приложения, точную конфигурацию proxy и фазу транзакции до её завершения. Crash до фиксации active возвращает старые маршруты/приложения; crash после фиксации завершает остановку прежнего цвета. Незавершённое восстановление оставляет intent и не сообщает успех. Изменение bind mounts или неожиданного upstream блокирует выпуск.

Первый ввод сохраняет legacy приложения как предыдущую сторону. Их нельзя удалять до успешного первого smoke. Глобальный Caddy не пересоздаётся; конфигурация пишется в существующий inode bind mount, проверяется и reload.

Webhook сохраняет ISR

После проверенного backup выполняется dry-run по webhook URL в Strapi. Только известные внутренние адреса прежнего web заменяются на https://gheilt.mxsource.xyz/api/webhooks/strapi, общий для обоих цветов и отката. Подпись, events, enabled и редакторские данные не меняются; произвольные внешние webhooks сохраняются. Candidate читает настройку при запуске, прежняя CMS — при восстановлении. Production принадлежит SourceCraft; GitHub Actions отключены, CI secrets/variables удалены, исторический репозиторий архивирован.

У действующих legacy GHCR-образов на проверке 2026-10-06 нет OCI revision label. Поэтому первый guard старой стороны проверяет её фактический runtime digest и файлы без утверждения о доказанном build SHA. Исключение применяется только к текущей legacy стороне; новые SourceCraft кандидаты обязаны иметь exact revision.

Единственный владелец production

Controller вызывает transaction только при production/owner.json с provider=sourcecraft. До этого новые схемы authority не дают права менять production. GitHub Actions отключены на уровне repository; все четыре GitHub workflow удалены. Выполняющихся GitHub job при отключении не было. Единственный владелец доставки — SourceCraft; исторические GHCR-образы работают до первого переключения цвета, но GitHub больше не может их обновлять. Caddy собирается отдельным manual workflow при изменении proxy, а не на каждый application commit.

После успешного smoke активный receipt используется для охлаждения staging только с теми же branch/head/images/generation. Повторные poll могут завершить отложенное охлаждение; новую staging generation они не останавливают. Если ветка ушла вперёд, receipt отсутствует или соответствует другой сборке, controller записывает pending и сохраняет прежний production. Отказ guard/smoke фиксируется отдельно как failed; повтор не перемещает stable tag.