Текст и данные · Инструкция
Docker HEALTHCHECK: start-period и start-interval
Docker HEALTHCHECK: start-period и start-interval нужны для двух разных этапов проверки контейнера.
Короткий ответ
Используйте `--start-period` как время на инициализацию приложения, а `--start-interval` — как частоту проб во время этой инициализации. После завершения стартового периода Docker переходит на обычный `--interval`; `--start-interval` требует Docker Engine 25.0+.
Как Docker переводит контейнер из starting в healthy или unhealthy
Наличие процесса в состоянии running ещё не означает, что приложение готово принимать запросы. Инструкция HEALTHCHECK добавляет отдельное состояние здоровья: сначала контейнер имеет статус `starting`, успешная проверка переводит его в `healthy`, а серия неудач может сделать `unhealthy`. Команда проверки должна завершаться кодом 0 при успехе и 1 при проблеме; код 2 зарезервирован. Важный нюанс — счётчик неудач зависит от стартового периода: приложение может несколько раз не пройти probe во время прогрева и при этом не получить ранний `unhealthy`. Это полезно для сервисов, которые поднимают схему базы, прогревают кеш или загружают модель перед готовностью.
Совет: Проверяйте готовность сервиса, а не просто наличие процесса. Для HTTP-приложения лучше обращаться к лёгкому health endpoint, который реально отражает способность обслуживать запрос.
Чем start-period отличается от start-interval и interval
`--start-period` — это длительность окна инициализации. Пока оно действует, провалы проверки не учитываются как обычные последовательные failures для перехода в `unhealthy`; однако успешная проверка завершает фазу запуска, и последующие сбои уже считаются штатно. `--start-interval` отвечает не за длительность, а за паузу между проверками внутри стартового периода. После запуска применяется `--interval`, то есть обычный интервал между healthcheck. В актуальной документации Docker значения по умолчанию: interval 30 секунд, timeout 30 секунд, start-period 0 секунд, start-interval 5 секунд и retries 3. Опция start-interval доступна в Docker Engine 25.0 и новее.
Предупреждение: Если CI или серверы ещё работают на старом Engine, не добавляйте `--start-interval` без проверки совместимости.
Как подобрать параметры для медленно запускающегося сервиса
- Измерьте реальный холодный старт: Запустите контейнер несколько раз и замерьте, когда endpoint готовности начинает стабильно отвечать. Не выбирайте start-period только «на глаз».
- Добавьте запас к start-period: Если сервис обычно готов за 20 секунд, стартовый период в 30–40 секунд может покрыть нормальные колебания, но не должен маскировать многоминутный зависший запуск.
- Выберите start-interval: Во время запуска проверки можно делать чаще, например каждые 2–5 секунд, чтобы сервис быстро стал healthy после фактической готовности.
- Настройте обычный interval: После старта частые probes часто не нужны. Установите интервал, который обнаруживает сбой достаточно быстро и не создаёт лишнюю нагрузку.
- Ограничьте timeout и retries: Timeout должен отражать реальное время ответа health endpoint. Retries защищает от единичного краткого сбоя.
- Проверьте docker inspect: После запуска посмотрите статус и историю healthcheck, убедитесь, что переходы `starting → healthy` происходят ожидаемо и вывод команды проверки остаётся коротким.
Важно: Слишком длинный start-period способен скрыть реальную ошибку запуска. Если приложение никогда не становится готовым, оно должно быстро показать проблему.
Параметры HEALTHCHECK и их роль
[object Object]
Пример Dockerfile и как его читать
Для сервиса, который обычно поднимается за 15–20 секунд, конфигурация может выглядеть так: `HEALTHCHECK --start-period=30s --start-interval=3s --interval=30s --timeout=3s --retries=3 CMD curl -fsS http://localhost:8080/health || exit 1`. В первые 30 секунд Docker запускает probe примерно каждые 3 секунды; ранние неудачи в пределах стартового периода не расходуют обычный лимит retries. Как только проверка успешно пройдёт, контейнер считается запущенным, и дальнейшие последовательные failures уже учитываются. После стартовой фазы проверки идут с обычным interval 30 секунд. В реальном проекте endpoint не должен выполнять тяжёлую бизнес-операцию: задача healthcheck — быстро и предсказуемо показать работоспособность сервиса.
Как не превратить healthcheck в источник нагрузки
Healthcheck запускается внутри контейнера, поэтому слишком тяжёлая команда конкурирует с самим приложением за CPU, память, файловые дескрипторы и сетевые соединения. Не стоит делать полноценный пользовательский сценарий, крупный SQL-запрос или обращение к десятку внешних зависимостей каждые несколько секунд. Хороший probe быстро отвечает на узкий вопрос: способен ли сервис обслуживать запросы в пределах локального контекста. Для readiness-подобного поведения иногда достаточно собственного `/health` endpoint, который проверяет критичные внутренние компоненты без тяжёлой работы. Частоту выбирайте из требований к времени обнаружения сбоя, а не по принципу «чем чаще, тем надёжнее».
Как читать временную шкалу HEALTHCHECK на конкретном примере
Допустим, контейнеру обычно нужно около 18 секунд на миграции и прогрев, а HEALTHCHECK задан как `--start-period=30s --start-interval=3s --interval=30s --timeout=3s --retries=3`. Во время стартового окна Docker запускает проверки с частотой start-interval, поэтому готовность может быть замечена вскоре после того, как приложение действительно начинает отвечать. Если первые несколько проверок завершаются кодом 1 до готовности, они не расходуют обычный лимит retries. Но как только одна проверка успешна, контейнер считается запущенным: последующие последовательные ошибки уже учитываются для статуса unhealthy. После стартовой фазы частота меняется на обычный interval. Именно поэтому start-period и start-interval нельзя заменять одним большим interval: первый управляет правилами учёта неудач при инициализации, второй — тем, как часто Docker пробует заметить готовность внутри этого окна.
Что проверять, если контейнер слишком долго остаётся starting
Сначала отделите проблему healthcheck от проблемы приложения. Выполните команду проверки вручную внутри контейнера и посмотрите её код возврата, время выполнения и текст ошибки. Затем откройте `docker inspect` и историю Health, чтобы понять, запускается ли probe вообще и не упирается ли он в timeout. Проверьте, что утилита из команды действительно присутствует в финальном image: частая ошибка — использовать `curl` в healthcheck минимального образа, где curl не установлен. Если приложение готово, но проверка всё равно падает, сравните адрес, порт, протокол и путь endpoint с фактической конфигурацией сервиса. Если же сам сервис ещё не готов, не лечите это бесконечным увеличением start-period: измерьте причину долгой инициализации. Параметры HEALTHCHECK должны отражать реальный жизненный цикл приложения, а не скрывать зависшую миграцию или недоступную зависимость.
Перед коммитом Dockerfile проверьте
- HEALTHCHECK присутствует в финальном stage образа и не перекрыт поздней инструкцией.
- В контейнере есть утилита, которую вызывает probe: curl/wget не стоит считать автоматически доступными.
- Код 0 означает успех, код 1 — проблему; зарезервированный код 2 не используется.
- start-period покрывает нормальный запуск, но не скрывает вечную инициализацию.
- start-interval используется только там, где Docker Engine 25.0+ гарантирован.
- Вывод проверки не содержит секретов и остаётся коротким.
Что учитывать
Условия меняются. Страница отражает состояние на 2026-09-20; при расхождении с официальной документацией приоритет у первоисточника.
Источники и проверка
Фактическая часть сверена по первичным источникам (в т.ч. Dockerfile reference). Пример и формулировки — редакция N1RO на 2026-09-20.