Пошук уроків, статей та іншого контенту
Додасте healthcheck, щоб Docker розрізняв запущений контейнер і справді готовий до роботи сервіс.
healthcheckСтатус Up означає лише те, що основний процес контейнера запущений. Це не гарантує, що сервіс:
завершив ініціалізацію;
приймає HTTP-запити;
може підключитися до залежностей;
не перебуває у стані помилки.
healthcheck додає перевірку, яку Docker регулярно виконує всередині контейнера. За її результатом контейнер може мати один із станів:
starting — перевірка ще не завершилася або триває період запуску;
healthy — останні перевірки успішні;
unhealthy — необхідна кількість перевірок завершилася невдало.
Важливо: стан unhealthy сам по собі не перезапускає контейнер. Для автоматичного перезапуску потрібні окремі параметри політики перезапуску або оркестратора.
healthcheck у DockerfileСтворимо невеликий HTTP-сервіс Node.js із маршрутом /health.
server.jsconst http = require("node:http");
const server = http.createServer((request, response) => {
if (request.url === "/health") {
response.writeHead(200, { "Content-Type": "text/plain" });
response.end("OK\n");
return;
}
response.writeHead(200, { "Content-Type": "text/plain" });
response.end("Service is running\n");
});
server.listen(3000, "0.0.0.0", () => {
console.log("Server is listening on port 3000");
});DockerfileFROM node:22-alpine
WORKDIR /app
COPY server.js .
EXPOSE 3000
HEALTHCHECK --interval=10s --timeout=3s --start-period=5s --retries=3 \
CMD-SHELL wget --no-verbose --tries=1 --spider http://127.0.0.1:3000/health || exit 1
CMD ["node", "server.js"]Параметри HEALTHCHECK у цьому прикладі:
--interval=10s — запускати перевірку кожні 10 секунд;
--timeout=3s — вважати перевірку невдалою, якщо вона триває довше 3 секунд;
--start-period=5s — дати сервісу 5 секунд на запуск;
--retries=3 — позначити контейнер як unhealthy після трьох невдалих перевірок поспіль;
CMD-SHELL — виконати команду через shell усередині контейнера.
Команда wget надсилає запит до http://127.0.0.1:3000/health. Якщо сервіс повертає успішний HTTP-відповідь, команда завершується з кодом 0, і перевірка вважається успішною.
Зберіть образ і запустіть контейнер:
docker build -t healthcheck-demo .
docker run -d --name healthcheck-demo -p 3000:3000 healthcheck-demoПеревірте стан контейнера:
docker psУ колонці STATUS через кілька секунд з’явиться приблизно такий статус:
Up 20 seconds (healthy)Перевірити сам сервіс можна з хостової системи:
curl http://localhost:3000/healthРезультат:
OKКоманда docker inspect показує детальний результат останніх перевірок:
docker inspect --format '{{json .State.Health}}' healthcheck-demoУ результаті буде об’єкт із поточним станом і журналом перевірок:
{
"Status": "healthy",
"FailingStreak": 0,
"Log": [
{
"ExitCode": 0,
"Output": "..."
}
]
}Для зручнішого перегляду можна вивести лише статус:
docker inspect --format '{{.State.Health.Status}}' healthcheck-demoМожливі результати:
startinghealthyunhealthyПереглянути журнали самого застосунку можна звичайною командою:
docker logs healthcheck-demoЩоб побачити стан unhealthy, змініть маршрут /health, наприклад повертайте статус 503:
if (request.url === "/health") {
response.writeHead(503, { "Content-Type": "text/plain" });
response.end("Service is not ready\n");
return;
}Після повторного створення образу та контейнера:
docker rm -f healthcheck-demo
docker build -t healthcheck-demo .
docker run -d --name healthcheck-demo -p 3000:3000 healthcheck-demoЧерез кілька невдалих перевірок Docker покаже:
docker inspect --format '{{.State.Health.Status}}' healthcheck-demounhealthyКонтейнер при цьому продовжить працювати. healthcheck лише повідомляє Docker про стан сервісу, але не зупиняє його і не виправляє причину помилки.
healthcheck у Docker ComposeПеревірку можна описати не в Dockerfile, а у файлі compose.yaml:
services:
app:
build: .
ports:
- "3000:3000"
healthcheck:
test:
[
"CMD",
"wget",
"--no-verbose",
"--tries=1",
"--spider",
"http://127.0.0.1:3000/health"
]
interval: 10s
timeout: 3s
start_period: 5s
retries: 3У цьому випадку test використовує форму CMD: Docker запускає wget без shell.
Запустіть сервіс:
docker compose up -d --buildПеревірте стан:
docker compose psУ виведенні буде видно стан на кшталт:
Up ... (healthy)У Compose параметри мають те саме призначення:
interval відповідає за період між перевірками;
timeout задає максимальний час однієї перевірки;
start_period визначає період запуску;
retries задає кількість послідовних помилок.
Якщо healthcheck заданий одночасно в Dockerfile і compose.yaml, конфігурація Compose використовується для запуску через Compose.
Команда перевірки має перевіряти саме готовність сервісу, а не лише наявність процесу.
Для HTTP-сервісу зазвичай перевіряють спеціальний endpoint:
/healthТакий endpoint має:
бути швидким;
не змінювати дані;
повертати успішний статус лише тоді, коли сервіс справді готовий;
не вимагати складної автентифікації для внутрішньої перевірки.
Для прикладу, перевірка на кшталт ps підтверджує, що процес існує, але не показує, чи приймає він запити:
HEALTHCHECK CMD-SHELL pgrep node || exit 1Для HTTP-сервісу перевірка endpoint зазвичай корисніша:
HEALTHCHECK CMD-SHELL wget --no-verbose --tries=1 --spider http://127.0.0.1:3000/health || exit 1Відкритий порт не означає, що всі компоненти застосунку готові. Сервіс може приймати TCP-з’єднання, але повертати помилки на запити.
Краще перевіряти endpoint, який відображає реальний стан застосунку.
Наприклад, у мінімальному образі може не бути curl. Якщо healthcheck використовує відсутню команду, кожна перевірка буде невдалою.
Переконайтеся, що команда доступна:
docker run --rm healthcheck-demo which wgetАбо встановіть потрібний інструмент під час побудови образу.
localhost хостової системиhealthcheck виконується всередині контейнера. Адреса:
127.0.0.1посилається на сам контейнер, а не на хостову систему. Для сервісу, який слухає порт 3000 у цьому самому контейнері, правильним буде:
http://127.0.0.1:3000/healthstart_periodЯкщо застосунок довго запускається, Docker може почати рахувати невдалі перевірки ще до завершення ініціалізації. У такому разі збільшіть start_period.
Статус unhealthy не перезапускає контейнер автоматично. Він лише фіксує невдалий стан, який можуть використовувати Docker Compose, системи моніторингу або оркестратори.
Якщо endpoint повертає HTTP 503, 404 або інший невдалий статус, команда на кшталт wget --spider зазвичай завершується з помилкою. Переконайтеся, що endpoint повертає успішний статус саме тоді, коли сервіс готовий.
Up означає, що процес контейнера працює, але не обов’язково готовий обслуговувати запити.
HEALTHCHECK додає регулярну перевірку стану сервісу.
Docker використовує стани starting, healthy і unhealthy.
Перевірка повинна завершуватися кодом 0, коли сервіс готовий.
interval, timeout, start_period і retries керують частотою та умовами перевірки.
Результат можна переглянути через docker ps і docker inspect.
unhealthy не перезапускає контейнер автоматично.