Docker Compose: container healthy check timed out — Исправление
Механизм оркестрации depends_on и подсистема Healthcheck
Ошибка ERROR: dependency failed to start: container is unhealthy или container healthy check timed out возникает при использовании механизма управления зависимостями depends_on с условием condition: service_healthy. Docker Compose запускает зависимый сервис только после того, как целевой контейнер перейдет из статуса starting в статус healthy. Если команда проверки здоровья (healthcheck probe) возвращает ненулевой код выхода (exit code > 0) или не успевает завершиться за время timeout на протяжении всех попыток retries, запуск всего стека аварийно прерывается.
Бизнес-риски:
Полный сбой автоматического развертывания приложений, каскадный отказ связанных сервисов (микросервисы не могут подключиться к нестартовавшей БД), задержки релизов.
Таблица параметров директивы Healthcheck
| Параметр | Рекомендуемое значение | Назначение |
|---|---|---|
test | ['CMD', 'curl', '-f', 'http://localhost:8080/health'] | Команда проверки жизнеспособности внутри контейнера. |
interval | 10s - 30s | Интервал времени между последовательными проверками. |
timeout | 5s - 10s | Максимальное время ожидания ответа на одну проверку. |
retries | 3 - 5 | Количество последовательных неудач до статуса unhealthy. |
start_period | 30s - 60s | Время на холодный старт (проверки в этот период не штрафуют статус). |
Пошаговая оптимизация и отладка проверок Healthcheck
Сценарий 1: Увеличение start_period для тяжелых сервисов (БД, Java/Spring)
Тяжелые базы данных или Java-приложения долго инициализируют структуры при первом старте:
services:
database:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U postgres']
interval: 10s
timeout: 5s
retries: 5
# Параметр для предотвращения таймаута при инициализации:
start_period: 45s
api:
image: myapi:latest
depends_on:
database:
condition: service_healthyСценарий 2: Тестирование команды Healthcheck вручную внутри контейнера
Проверьте, установлена ли утилита проверки (curl/wget/pg_isready) в базовом образе:
# Вход в работающий контейнер зависимости
docker exec -it <container_name> sh
# Ручной запуск команды проверки и просмотр кода выхода:
pg_isready -U postgres
echo $?Сценарий 3: Просмотр логов неудавшихся проверок Healthcheck
Узнайте точную причину падения проверок через детальную инспекцию Docker:
# Получение последних результатов проверок healthcheck и их вывода
docker inspect <container_name> --format='{{json .State.Health}}' | jq .Типовые ошибки администраторов
- Использование curl в легковесных alpine-образах: В базовых образах Alpine утилита
curlотсутствует. Используйтеwget -q --spider http://127.0.0.1:80/ || exit 1. - Отсутствие start_period при миграциях БД: Если сервис выполняет долгие миграции базы данных при первом старте, он гарантированно получит статус unhealthy без start_period.
ITSTM настроит надежные readiness/liveness пробы, оптимизирует запуск баз данных и обеспечит 100% стабильность ваших стеков.
Частые вопросы (FAQ)
Чем отличается CMD от CMD-SHELL в директиве test?
CMD вызывает бинарник напрямую без шелла: ['CMD', 'curl', 'localhost']. CMD-SHELL оборачивает команду в shell: ['CMD-SHELL', 'curl localhost || exit 1'].
Можно ли использовать depends_on без healthcheck?
Да, но без condition: service_healthy Docker Compose просто запустит контейнеры одновременно, не дожидаясь реальной готовности приложения внутри.
Как временно отключить healthcheck у наследуемого образа?
В блоке сервиса укажите: healthcheck: disable: true.
Какой код выхода считается успешным для Healthcheck?
Строго код 0. Код 1 означает unhealthy. Любые другие коды выхода зарезервированы и также переводят контейнер в unhealthy.