Container Health Checks and Restart Policies

A
Author
27 May, 2026 1 min read 515 views

A running process isn't necessarily a working one. It might be deadlocked, out of database connections or stuck in a crash loop. Health checks and restart policies help Docker notice and react.

HEALTHCHECK in a Dockerfile

HEALTHCHECK --interval=30s --timeout=3s --start-period=20s --retries=3 \
  CMD wget -qO- http://localhost:3000/healthz || exit 1
  • --start-period: grace time for slow startups before failures count.
  • --retries: consecutive failures before the container is marked unhealthy.
  • The command must exit 0 for healthy and 1 for unhealthy.
docker ps                                   # STATUS shows (healthy) / (unhealthy)
docker inspect --format '{{json .State.Health}}' api

A useful health endpoint

app.get('/healthz', async (req, res) => {
  try {
    await db.query('SELECT 1');           // can we reach what we need?
    res.json({ status: 'ok' });
  } catch {
    res.status(503).json({ status: 'db unavailable' });
  }
});

Keep it fast and cheap; it runs every few seconds. Avoid checking optional third-party services, or one partner outage will mark every container unhealthy.

Restart policies

docker run -d --restart unless-stopped my-api
  • no - default; never restart.
  • on-failure[:max] - restart if the process exits with a non-zero code.
  • always - always restart, including after the Docker daemon restarts.
  • unless-stopped - like always, but not if you stopped it manually. A good default on single servers.

In Compose and Kubernetes

Compose supports healthcheck and restart keys per service, and can wait for a healthy dependency. Kubernetes ignores the Dockerfile HEALTHCHECK and uses its own liveness, readiness and startup probes instead.

Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.