fix(tradein/devops): проверка всего стека после деплоя + запас на остановку #2540

Merged
lekss361 merged 1 commit from fix/tradein-audit-devops into main 2026-07-26 22:57:42 +00:00
Owner

1. Пост-деплойная проверка щупала только бэкенд

deploy-tradein.yml — сломанный фронтенд или скрапер помечались успешным деплоем, отката не происходило.

Добавлены четыре проверки перед записью маркера успеха: фронтенд (curl изнутри бэкенд-контейнера на frontend:3000/trade-in/ — префикс запечён в prod-образе, поэтому голый / даёт 404), браузер (browser:3000/health), и проверка состояния через docker inspect для tgbot и scraper — у них HTTP-сервера нет вовсе, это голые asyncio-процессы. Последние два проверяются только если реально входят в текущий деплой. Любая неудача — выход с ошибкой до записи маркера, как и у существующей проверки бэкенда.

2. Не было запаса времени на остановку

docker-compose.prod.yml:

  • backend — 60 секунд: генерация PDF идёт синхронным путём в пуле потоков, WeasyPrint.write_pdf без верхней границы, а timeout_graceful_shutdown у uvicorn по умолчанию не задан — единственный реальный ограничитель это Docker. Раньше был дефолт в 10 секунд, то есть отчёт получал SIGKILL посреди генерации.
  • browser — 90 секунд: aiohttp ловит SIGTERM и даёт себе 60 секунд на завершение, плюс запас на закрытие camoufox.

Значения обоснованы документацией uvicorn и aiohttp, по аналогии с уже существующей парой у scraper и tgbot (120 секунд под таймаут кооперативного завершения 100).

3. Манифест миграций

Дописаны 173-186 — они давно на проде и теперь защищены контрактным тестом от случайного переименования.

Миграции 187 и 188 намеренно не добавлены: агент нашёл в истории репозитория прямой прецедент (коммит 5eadae1e), где ровно эту строку добавили и тут же убрали с обоснованием — незамерженное имя миграции в манифесте лишает возможности переименовать файл до мержа. Веб-чат в этот момент как раз дорабатывался. Решение задокументировано в манифесте со ссылкой на конкретный коммит.

Test plan

  • uv run pytest -q — 2658 passed, 8 skipped; миграционные тесты 4 passed
  • yaml.safe_load на обоих YAML, bash -n на извлечённом скрипте деплоя
  • Реальный прогон новых проверок на проде не выполнялся — только синтаксис и разбор сетевой топологии
  • Значения 60 и 90 секунд обоснованы документацией, но не замерены эмпирически под нагрузкой
## 1. Пост-деплойная проверка щупала только бэкенд `deploy-tradein.yml` — сломанный фронтенд или скрапер помечались успешным деплоем, отката не происходило. Добавлены четыре проверки перед записью маркера успеха: фронтенд (`curl` изнутри бэкенд-контейнера на `frontend:3000/trade-in/` — префикс запечён в prod-образе, поэтому голый `/` даёт 404), браузер (`browser:3000/health`), и проверка состояния через `docker inspect` для `tgbot` и `scraper` — у них HTTP-сервера нет вовсе, это голые asyncio-процессы. Последние два проверяются только если реально входят в текущий деплой. Любая неудача — выход с ошибкой **до** записи маркера, как и у существующей проверки бэкенда. ## 2. Не было запаса времени на остановку `docker-compose.prod.yml`: - **backend — 60 секунд**: генерация PDF идёт синхронным путём в пуле потоков, `WeasyPrint.write_pdf` без верхней границы, а `timeout_graceful_shutdown` у uvicorn по умолчанию не задан — единственный реальный ограничитель это Docker. Раньше был дефолт в 10 секунд, то есть отчёт получал SIGKILL посреди генерации. - **browser — 90 секунд**: aiohttp ловит SIGTERM и даёт себе 60 секунд на завершение, плюс запас на закрытие camoufox. Значения обоснованы документацией uvicorn и aiohttp, по аналогии с уже существующей парой у scraper и tgbot (120 секунд под таймаут кооперативного завершения 100). ## 3. Манифест миграций Дописаны 173-186 — они давно на проде и теперь защищены контрактным тестом от случайного переименования. Миграции **187 и 188 намеренно не добавлены**: агент нашёл в истории репозитория прямой прецедент (коммит `5eadae1e`), где ровно эту строку добавили и тут же убрали с обоснованием — незамерженное имя миграции в манифесте лишает возможности переименовать файл до мержа. Веб-чат в этот момент как раз дорабатывался. Решение задокументировано в манифесте со ссылкой на конкретный коммит. ## Test plan - [x] `uv run pytest -q` — 2658 passed, 8 skipped; миграционные тесты 4 passed - [x] `yaml.safe_load` на обоих YAML, `bash -n` на извлечённом скрипте деплоя - [ ] Реальный прогон новых проверок на проде не выполнялся — только синтаксис и разбор сетевой топологии - [ ] Значения 60 и 90 секунд обоснованы документацией, но не замерены эмпирически под нагрузкой
lekss361 added 1 commit 2026-07-26 21:44:03 +00:00
fix(tradein/devops): post-deploy health для всего стека + grace period + manifest
All checks were successful
CI Trade-In / changes (pull_request) Successful in 12s
CI / changes (pull_request) Successful in 12s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 5m13s
3768aa2b5d
1. deploy-tradein.yml: health-check раньше щупал только backend — сломанный
   frontend (404 из-за basePath), упавший browser или crash-loop tgbot/scraper
   помечались успешным деплоем без отката. Добавлены: frontend (curl изнутри
   backend-контейнера на /trade-in/, basePath запечён в prod-образ), browser
   (/health, живёт даже без поднятых camoufox-инстансов), tgbot/scraper
   (docker inspect state=running с двойной проверкой — у них нет HTTP,
   bare python-процессы). Проверяются только сервисы, реально входящие в
   $SERVICES текущего деплоя.

2. docker-compose.prod.yml: backend (60s) и browser (90s) получили
   stop_grace_period — раньше дефолтные docker 10s SIGKILL'или PDF-экспорт
   (WeasyPrint write_pdf, sync route → Starlette threadpool, uvicorn
   timeout_graceful_shutdown=None по умолчанию — единственный backstop это
   Docker) и headless-навигацию browser (aiohttp shutdown_timeout=60s по
   умолчанию + время на закрытие Firefox-инстансов в _on_cleanup) прямо
   посреди работы.

3. _manifest_applied.txt: дописаны 173-186 (давно применены на проде,
   contract-тест их не защищал от rename/rm). 187/188 (веб-чат поддержки)
   НАМЕРЕННО не добавлены — прецедент в этом же репо (commit 5eadae1e, L5):
   миграция, добавленная в manifest ДО того как осела на проде в финальном
   виде, блокирует легитимный rename; фича ещё активно дорабатывается
   параллельно.
lekss361 merged commit bcb903cfa2 into main 2026-07-26 22:57:42 +00:00
lekss361 deleted branch fix/tradein-audit-devops 2026-07-26 22:57:42 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2540
No description provided.