diff --git a/caddy/deploy-window.caddy.snippet b/caddy/deploy-window.caddy.snippet new file mode 100644 index 00000000..971464de --- /dev/null +++ b/caddy/deploy-window.caddy.snippet @@ -0,0 +1,54 @@ +# ═══════════════════════════════════════════════════════════════════════════ +# caddy/deploy-window.caddy.snippet — ответ на окно деплоя (#3274) +# +# Импортируется ВНУТРЬ `handle_errors 502 503 504 { ... }` (см. apps.caddy): +# сам по себе снипет ничего не перехватывает, он только решает, ЧТО отдать, +# когда апстрим не отвечает. +# +# ЧТО ЭТО ЛЕЧИТ, А ЧТО НЕТ. Каждый деплой tradein-frontend/tradein-backend +# оставляет окно 30–90 с, в котором контейнера просто нет: Caddy набирает +# новый апстрим сразу, тот ещё не слушает (замер по access-логам, #3274 — +# все 502 кластеризуются на окнах мержа, duration < 2 мс = мгновенный отказ +# соединения). Снипет НЕ УБИРАЕТ окно — он меняет то, что видит человек и +# клиент внутри окна. Настоящее лечение (готовность нового контейнера до +# переключения) — п.1 issue, решение владельца, здесь его нет. +# +# ПОЧЕМУ 503, А НЕ 502. 502 значит «апстрим ответил мусором» — постоянная +# поломка; поисковик по нему выкидывает страницу из индекса, клиентские +# библиотеки не ретраят. 503 + `Retry-After: 30` — стандартный код «временно +# недоступен, приходи через 30 секунд»: Googlebot держит страницу в индексе, +# HTTP-клиенты понимают, что повтор осмыслен. +# +# ПОЧЕМУ ДВА ТЕЛА. `/trade-in/api/*` вызывают из JS и внешних клиентов — они +# парсят JSON, и HTML-страница у них превращается в ошибку разбора вместо +# читаемого статуса. Всё остальное открывает человек браузером. +# +# ВНЕШНИХ РЕСУРСОВ В СТРАНИЦЕ НЕТ ВООБЩЕ — ни шрифта, ни CSS-файла, ни +# картинки. В окне деплоя они пришли бы с того же мёртвого апстрима, и +# страница-заглушка отрисовалась бы голым текстом. Отсюда же инлайновые +# `style=` вместо блока `