5.7 KiB
BRD: Healthcheck enduro-trails-app падает: в контейнере нет curl
Work Item: ET-015 Тип: Bugfix / Infrastructure Приоритет: Низкий (приложение работает) / Важно для мониторинга Дата: 2026-06-05 Запросил: Слава
1. Контекст
Контейнер enduro-trails-app-1 (запускается из репозитория enduro-trails)
на тестовой среде mva154 (https://openclaw.mva154.duckdns.org/enduro/)
показывает в Docker статус unhealthy уже ~31 час с FailingStreak=3762,
при том что само приложение работает:
curl снаружи :5556 → HTTP 200(~7 мс отклик);- в логах живой трафик
200 OK; RestartCount=0(контейнер не перезапускался).
2. Корень проблемы
В docker-compose.yml healthcheck настроен как:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5556/api/health"]
Базовый образ — python:3.12-slim (см. Dockerfile). В slim-варианте
нет утилиты curl. Каждый цикл healthcheck завершается:
exec: "curl": executable file not found in $PATH
exit code = -1
Docker трактует это как «проверка провалена» и через retries=3 помечает
контейнер unhealthy. На самом деле приложение здорово.
Дополнительный факт: эндпоинт /api/health существует в коде
(src/api/main.py:1224, отдаёт {"status": "ok", ...}), так что
двойной поломки (несуществующий путь) нет — проблема исключительно
в отсутствии curl.
3. Бизнес-проблема
- Ложные алерты в мониторинге. Любая система оповещений, опирающаяся
на
docker inspect ... .State.Health.Status, будет постоянно кричать об инциденте, который не существует. - Эрозия доверия к мониторингу. Если
unhealthyвсегда ложный, его игнорируют — и пропустят настоящий инцидент, когда он случится. - Невозможность построения SLO/SLA. Метрика «доступность контейнера» деградирована и непригодна для отчётности.
4. Цель
Healthcheck контейнера app должен честно отражать состояние
приложения: healthy, когда HTTP-эндпоинт /api/health на :5556
отвечает 200 OK; unhealthy, когда не отвечает.
5. Стейкхолдеры
| Роль | Имя / Группа | Интерес |
|---|---|---|
| Заказчик | Слава | Корректный мониторинг тестовой и будущей prod-среды |
| Исполнитель | claude-bot | Реализация фикса |
| Эксплуатация | mva154 host owner | Минимальный размер образа, никаких лишних пакетов |
6. Ограничения и нефункциональные требования
- Размер образа не должен заметно расти. Добавление
curlчерезapt-get installтянет ~10 МБ зависимостей + слой APT-кэша → нежелательно. Предпочтительно использовать то, что уже есть в образе (Python). - Время выполнения healthcheck не должно превышать
timeout: 5s(текущее значение в compose). Реальное время отклика/api/health~7 мс, запас огромный. - Совместимость с Docker Engine ≥ 20.10 (на mva154 стоит свежий).
- Никаких изменений в логике приложения — эндпоинт
/api/healthуже существует и его поведение менять не нужно.
7. Out of scope
- Доработка содержимого
/api/health(например, добавление проверки OSRM, тайлов, диска) — отдельный work item, если понадобится. - Healthcheck для сервиса
gps-collector(batch profile) — у него нет открытого порта иrestart: "no", healthcheck неуместен. - Healthcheck-настройки на стороне Gitea Actions / CI.
8. Сценарий «как должно стать»
- Образ собирается без добавления
curl. docker compose up -d appподнимает контейнер.- Через ≤
interval * retries(= 30s × 3 = 90s, с учётомstart_periodесли задан)docker inspect ... .State.Health.Statusвозвращаетhealthy. - Если приложение «зависает» (порт не отвечает) — healthcheck
честно фиксирует
unhealthyза то же окно.
9. Связи
- Затрагивает:
Dockerfile,docker-compose.yml. - Не затрагивает:
src/api/,src/web/, БД, тайлы. - Соседние ADR: глобальных архитектурных решений не требует —
локальное инженерное решение, оформляется в
06-adr/work-item.