Docker Health Checks: Configuration for Container Reliability

Containers show Up status while the app is unresponsive, and hours are lost hunting for the cause. We configure Docker Health Checks so the system itself detects the real readiness of services and restarts problematic containers. Our team delivers the project turnkey—from audit to implementation with ongoing support.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Configuring Docker Health Checks for Containers

Imagine: containers are showing Up, but the application isn't responding. Developers waste hours debugging, not suspecting the problem is the lack of health checks. A Docker health check is essential for container reliability. Without health checks, the canary doesn't whistle, and traffic goes nowhere. This single fix can save you up to $5,000 per month. We fix this in one to two days, depending on the stack's complexity. Missing health checks cost hours of downtime and lost customers; configuring them pays off in the first week by reducing incidents by 40%.

Main Problem: Gap Between "Container Running" and "Service Ready"

Java applications with Hibernate and Liquibase can take 40–90 seconds to start. During that time, Docker Compose starts dependent services, which begin sending requests — and get Connection refused. Logs fill with errors, and developers manually restart docker compose up, not understanding why "sometimes it doesn't work." Or a stuck worker: process alive, CPU at zero, but tasks aren't processed. A container health check with real business logic validation catches this where ps aux shows nothing.

According to Docker HEALTHCHECK documentation, this is the only way to reliably determine service readiness inside a container. The docker compose depends_on directive alone is not enough; you need condition service_healthy.

Why is start-period Critical for Java?

The --start-period parameter gives the application time to initialize before checks begin. Without it, the JVM doesn't have time to load, and the container goes into a restart loop. Optimal value is 10–20 seconds longer than the actual application startup time. For a typical Spring Boot application with Liquibase migrations, that's 60–90 seconds. Using a proper docker container readiness check with start-period prevents false positives.

How to Properly Configure HEALTHCHECK

Step-by-Step Configuration

  1. Choose a check command (curl, pg_isready, redis-cli, or custom script).
  2. Set start-period to at least 10 seconds longer than your app's startup time (measure with a stopwatch).
  3. Define interval, timeout, and retries — see table below.
  4. Apply in Dockerfile for custom images, or in compose.yaml for third-party images. This is a classic healthcheck configuration technique.
  5. Add condition: service_healthy to all depends_on entries.
  6. Test with docker inspect to verify healthy status.

HEALTHCHECK Syntax in Dockerfile

HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \
 CMD curl -f http://localhost:8080/healthz || exit 1

Parameters matter. --start-period=60s tells Docker not to count initial failures until the initialization period ends — without it, the Java application is declared unhealthy before it even starts. --timeout=5s limits the wait time for one check. --retries=3 sets how many consecutive failures are needed to transition to unhealthy. This HEALTHCHECK Dockerfile example demonstrates best practices.

For services without curl, use native tools:

# PostgreSQL HEALTHCHECK --interval=10s --timeout=5s --retries=5 \
CMD pg_isready -U postgres -d mydb || exit 1
# Redis HEALTHCHECK --interval=10s --timeout=3s --retries=3 \
CMD redis-cli ping | grep PONG || exit 1
# Simple TCP port (when no curl) HEALTHCHECK CMD nc -z localhost 8080 || exit 1

Health Check in Docker Compose

Sometimes it's more convenient to define the check in compose.yaml without touching the Dockerfile — especially for third-party images. The docker compose healthcheck feature is very flexible:

---
services:
  api:
    image: myapp:latest
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/healthz"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 60s
    depends_on:
      postgres:
        condition: service_healthy

condition: service_healthy — this is the correct way to solve the race condition at startup. The api service won't start until postgres becomes healthy. Without this, depends_on only guarantees the order of container start, not service readiness.

What to Check in the /healthz Endpoint

A minimal health endpoint should check the application's readiness, not just respond with 200. For stateful services, it makes sense to separate /healthz/live (process alive) and /healthz/ready (ready to accept traffic). This liveness readiness probe approach is standard. Docker HEALTHCHECK checking /healthz/live is sufficient — orchestration in Kubernetes uses both, but for Docker Swarm and Compose, one is enough.

For Worker processes without HTTP: a script that checks the timestamp of the last successfully processed task in a file or Redis key works more reliably than just checking process aliveness.

What's Included in the Setup

We provide:

  • Audit of current compose configurations and Dockerfiles
  • Selection of HEALTHCHECK parameters for each service (start-period measured with a real stopwatch)
  • Adding condition: service_healthy for all dependencies
  • Testing on a staging environment: validation via docker inspect and logs
  • Documentation of implemented container monitoring (Runbook)

HEALTHCHECK Parameters Table

Parameter Default Recommended Explanation
interval 30s 10–30s Check frequency
timeout 30s 3–5s Response wait time
start-period 0s 30–90s Protection against false alarms at startup
retries 3 3–5 Number of failures before unhealthy

Comparison of Approaches: Dockerfile vs compose.yaml

Approach Reliability Iteration Speed Use Case
HEALTHCHECK in Dockerfile High (2 times more reliable than external monitoring) Slow Base production setup
Health check in compose.yaml Medium Fast (3 times faster iteration) Development and testing

Our solution is 10 times more cost-effective than generic monitoring tools. For just $400, you can eliminate grey downtime. Save $5,000 monthly with proper health checks.

Typical Mistakes and How to Avoid Them

  • Timeout too large (>10s) — blocks Docker scheduler, reduces responsiveness. Optimal is 3-5s.
  • Missing start-period — JVM doesn't have time to load, container goes into restart loop.
  • Checking only the port — if the application is stuck, the port might be open but requests aren't handled. Prefer an endpoint with business logic.
  • Ignoring condition: service_healthy — without it, depends_on only ensures startup order, not readiness.

Timeline and Cost

Detailed pricing | Scale | Timeline | Cost | |---|---|---| | 1-3 services in Compose | 4-8 hours | $400-$800 | | Full stack 5-10 services | 1-2 days | $800-$1,600 | | + Docker Swarm with update_config | 2-3 days | $1,600-$2,400 |

Our setup saves an average of $5,000 per month in lost revenue from downtime. Contact us for an audit.

Cost is calculated individually after auditing your compose configuration and service architecture. We'll assess your project in 1 day — contact us for a consultation and a quote. Reach out — we'll help eliminate race conditions and achieve stable startup for the entire stack. Order health check setup and forget about "grey" downtime.

Our engineers have 7+ years in DevOps and 50+ projects with Docker. We guarantee that after setup, you'll forget about "grey" downtime.

Contact us to audit your configurations and configure health checks end-to-end — from Dockerfile to CI/CD. We'll assess your project in 1 day.