fix(infra): use python urllib for container healthcheck (ET-015) #30
Reference in New Issue
Block a user
Delete Branch "feature/ET-015-healthcheck-enduro-trails-app-"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Заменяем healthcheck сервиса
appвdocker-compose.ymlсcurl -f(отсутствует в базовомpython:3.12-slim, из-за чего контейнерenduro-trails-app-1≥31 час висит вunhealthyпри работающем приложении) на python one-liner через stdliburllib.request— без правокDockerfileиsrc/api/main.py, без ребилда образа (достаточноdocker compose up -d app).services.app.healthcheck.test):interval=30s/timeout=5s/retries=3сохранены; внутреннийtimeout=3строго меньше внешнегоtimeout: 5s(AC-07); добавленstart_period: 20s.[Unreleased] / Fixed.docs/work-items/ET-015/06-adr/ADR-020-healthcheck-via-python-urllib.md(создан архитектором ранее).Покрытие тестами
tests/static/test_healthcheck_compose.py— 10 тестов (ST-01..ST-07 + защита от регресса по target URL,start_period, baselineinterval/retries).tests/unit/test_healthcheck_oneliner.py— 6 тестов (UT-01..UT-03), исполняют ровно ту же one-liner-команду из compose черезsubprocessпротив локального мок-HTTPServer (200 / 301 / 404 / 500 / 503) и неиспользуемого порта. URL подменяется через_retarget, чтобы тестировать живой код, а не его копию.Все 16 тестов проходят локально.
Test plan
make test— все static + unit тесты ET-015 зелёные.make lint— ruff проходит.docker compose up -d appконтейнер становитсяhealthyза ≤ 120s (FailingStreak == 0).unhealthyза ≤ 120s.make deploy-test: E2E-01 —docker inspect enduro-trails-app-1 --format '{{.State.Health.Status}}'→healthy(streak 0) трижды (0, +5 мин, +10 мин).curl https://openclaw.mva154.duckdns.org/enduro/api/health→ HTTP 200,time_total < 1s.Refs: ET-015
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
Базовый образ `python:3.12-slim` не содержит `curl`, поэтому текущий healthcheck `["CMD", "curl", "-f", ...]` всегда падает (`exec: "curl": executable file not found`), и контейнер `enduro-trails-app-1` висит в статусе `unhealthy` (≥31 час, FailingStreak 3762 при RestartCount 0), несмотря на то что приложение исправно отвечает HTTP 200 на /api/health. Заменяем healthcheck на python one-liner через stdlib `urllib.request` (ADR-020). Изменения: • docker-compose.yml, сервис app: test: ["CMD", "python", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen(...timeout=3).status == 200 else 1)"] + start_period: 20s interval/timeout/retries сохранены (30s / 5s / 3). Внутренний urlopen(timeout=3) строго меньше внешнего healthcheck timeout=5s (AC-07). • Dockerfile НЕ меняется (никаких apt-get install curl/wget — BRD §6, AC-04). Деплой без ребилда: `docker compose up -d app` достаточно. • src/api/main.py НЕ меняется. Контракт /api/health сохранён (AC-08). Покрытие: - tests/static/test_healthcheck_compose.py — 10 тестов (ST-01..ST-07 + защита от регресса по target URL / start_period / baseline params). - tests/unit/test_healthcheck_oneliner.py — 6 тестов (UT-01..UT-03), исполняют ровно ту же one-liner-команду через subprocess против локального мок-HTTPServer (200/301/404/500/503) и неиспользуемого порта. URL подменяется через `_retarget`, чтобы тестировать живой код из compose, а не его копию. ADR: docs/work-items/ET-015/06-adr/ADR-020-healthcheck-via-python-urllib.md CHANGELOG: запись в [Unreleased] / Fixed. Refs: ET-015 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>