Пошук уроків, статей та іншого контенту
Додасте healthcheck і використаєте його стан, щоб запускати залежні сервіси лише після готовності компонента.
Запуск контейнера ще не означає, що застосунок усередині нього готовий приймати з'єднання.
Наприклад, контейнер PostgreSQL може вже перебувати у стані running, але сервер бази даних ще запускається. Якщо залежний сервіс спробує під'єднатися до бази одразу, з'єднання може завершитися помилкою.
healthcheck описує перевірку, за якою Docker визначає стан готовності контейнера:
starting — перевірки ще не завершилися або контейнер перебуває в періоді запуску;
healthy — остання перевірка успішна;
unhealthy — перевірка неуспішна кілька разів поспіль.
Стан healthcheck — це додаткова інформація про контейнер. Він не змінює основний стан контейнера running або exited.
Healthcheck задається в секції конкретного сервісу:
services:
database:
image: postgres:16-alpine
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
interval: 5s
timeout: 3s
retries: 5
start_period: 10sПараметри перевірки:
test — команда, яку Docker запускає всередині контейнера;
interval — інтервал між перевірками;
timeout — максимальний час очікування результату однієї перевірки;
retries — кількість послідовних невдалих перевірок до стану unhealthy;
start_period — час на початковий запуск, протягом якого невдалі перевірки не враховуються як остаточна помилка.
Команда перевірки має завершуватися кодом:
0, якщо компонент готовий;
будь-яким ненульовим кодом, якщо компонент не готовий.
У прикладі використано pg_isready — утиліту, яка входить до образу PostgreSQL і перевіряє готовність сервера приймати підключення.
testКоманду можна записати у двох основних форматах:
healthcheck:
test: ["CMD", "pg_isready", "-U", "app", "-d", "appdb"]або:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d appdb"]CMD запускає програму без shell. CMD-SHELL запускає команду через shell і зручний для операторів, змінних та складніших перевірок.
Щоб залежний сервіс очікував не лише запуску контейнера, а й успішного healthcheck, використовується розширений синтаксис depends_on:
services:
worker:
depends_on:
database:
condition: service_healthyУ цьому випадку Compose:
запускає контейнер database;
очікує, доки його healthcheck перейде у стан healthy;
запускає контейнер worker.
Це відрізняється від короткого синтаксису:
depends_on:
- databaseКороткий синтаксис задає порядок запуску контейнерів, але не гарантує готовність сервісу всередині контейнера.
Створіть файл compose.yaml:
services:
database:
image: postgres:16-alpine
environment:
POSTGRES_DB: appdb
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
interval: 5s
timeout: 3s
retries: 5
start_period: 10s
worker:
image: postgres:16-alpine
depends_on:
database:
condition: service_healthy
environment:
PGPASSWORD: secret
command:
- sh
- -c
- |
echo "Database is ready"
while true; do
psql -h database -U app -d appdb -c "SELECT now();"
sleep 10
doneЗапустіть сервіси:
docker compose upПід час першого запуску база даних може витратити кілька секунд на ініціалізацію. У цей час worker ще не запускатиме свою команду. Після успішної перевірки ви побачите повідомлення:
Database is readyПотім worker кожні десять секунд виконуватиме запит до PostgreSQL.
Переглянути стани сервісів можна командою:
docker compose psДля сервісу database стан матиме приблизно такий вигляд:
Up (healthy)Переглянути докладну інформацію про healthcheck можна через Docker CLI:
docker inspect --format='{{json .State.Health}}' "$(docker compose ps -q database)"Після завершення роботи з прикладом видаліть контейнери:
docker compose downHealthcheck має перевіряти саме ту умову, яка потрібна залежному сервісу.
Для різних компонентів це можуть бути:
PostgreSQL — перевірка готовності через pg_isready;
HTTP-сервіс — запит до спеціального endpoint, наприклад /health;
Redis — команда перевірки доступності Redis;
файловий сервіс — перевірка наявності потрібного файлу або каталогу.
Перевірка процесу недостатня. Наприклад, команда може працювати, але застосунок ще не відкрив порт або не підключився до бази даних. Тому краще перевіряти реальну готовність до обробки запитів.
Якщо в образі є curl, healthcheck для HTTP-сервісу може виглядати так:
healthcheck:
test: ["CMD-SHELL", "curl --fail http://localhost:8080/health || exit 1"]
interval: 10s
timeout: 3s
retries: 3
start_period: 15sВажливо, що команда виконується всередині контейнера. Якщо в образі немає curl, така перевірка не працюватиме. У такому разі потрібно використати наявну утиліту або додати необхідний інструмент до образу.
Параметри healthcheck потрібно узгоджувати з реальною швидкістю запуску сервісу.
Якщо start_period замалий:
повільний сервіс може передчасно перейти у стан unhealthy;
залежні сервіси не запустяться;
у логах можуть з'явитися помилки ще до завершення ініціалізації.
Якщо interval надто великий:
Compose довше чекатиме на готовність;
проблеми в сервісі виявлятимуться повільніше.
Для локального середовища часто достатньо коротких інтервалів. Для важчих сервісів варто врахувати час першого запуску, міграцій бази даних та інших обов'язкових операцій ініціалізації.
Healthcheck виконується протягом усього часу роботи контейнера, а не лише під час запуску.
Якщо після успішної перевірки сервіс стане недоступним:
Docker зафіксує невдалі перевірки;
після досягнення retries стан зміниться на unhealthy;
Docker Compose автоматично не перезапустить контейнер лише через цей статус.
Healthcheck повідомляє про стан контейнера, але сам по собі не є механізмом відновлення. Політики перезапуску та реакцію застосунку на стан залежності потрібно налаштовувати окремо.
depends_on без умовиdepends_on:
- databaseТакий запис гарантує лише порядок запуску контейнерів. Для очікування healthcheck використовуйте:
depends_on:
database:
condition: service_healthyВідкритий порт не завжди означає, що застосунок повністю готовий. Наприклад, HTTP-сервер може приймати TCP-з'єднання, але ще не завершити завантаження конфігурації.
Краще перевіряти endpoint або команду, яка підтверджує працездатність потрібної функції.
Якщо в образі немає curl, wget, pg_isready або іншої утиліти, healthcheck постійно завершуватиметься помилкою.
Перевіряйте команди в тому самому образі:
docker compose run --rm database pg_isready -U app -d appdbПеревірка не повинна залежати від другорядних функцій, якщо вони не потрібні для старту залежного сервісу. Інакше компонент може бути позначений як unhealthy, хоча основна функціональність уже доступна.
healthcheck перевіряє готовність компонента всередині контейнера.
Можливі стани healthcheck — starting, healthy та unhealthy.
Команда перевірки повинна завершуватися кодом 0, коли сервіс готовий.
depends_on з умовою service_healthy дає змогу запускати залежний сервіс після успішної перевірки.
Перевірка має підтверджувати реальну готовність сервісу, а не лише факт запуску процесу.
Healthcheck не перезапускає контейнер автоматично, якщо той став unhealthy.