Docker

Docker Healthchecks vs Orchestrator Probes for Production Containers

4 min read by DebuggedIt

Quick answer

A Docker HEALTHCHECK only reports a status; it does not restart or reroute anything by itself on plain Docker Engine. Orchestrator probes, such as those in...

A Docker HEALTHCHECK only reports a status; it does not restart or reroute anything by itself on plain Docker Engine. Orchestrator probes, such as those in Kubernetes, are tied to actions like restarting a container or removing it from load balancing. In production under an orchestrator, probes should be your primary mechanism, and HEALTHCHECK is mainly useful for Docker Compose and local development.

What Does a Docker HEALTHCHECK Actually Do?

The HEALTHCHECK instruction defines a command that Docker runs inside the container at a fixed interval. Based on the exit code, the container is marked healthy or unhealthy. That status appears in docker ps and docker inspect, and tools like Docker Compose can use it to delay starting dependent services.

HEALTHCHECK --interval=15s --timeout=3s --start-period=20s --retries=3 \
  CMD ["/app/healthcheck"]

On a standalone Docker Engine, an unhealthy status does not restart the container. Docker Swarm can replace unhealthy tasks, but behavior varies by orchestrator, so verify it in the documentation of the platform you run. Many Kubernetes setups ignore the Docker HEALTHCHECK entirely and rely on their own probe definitions.

This is the root of a common misunderstanding. Teams add a HEALTHCHECK, see the container marked unhealthy in the output, and assume the platform will fix the problem. In practice, the label is just information until something consumes it, such as a Compose dependency condition or a monitoring agent that alerts on it.

How Do Liveness, Readiness, and Startup Probes Differ?

Orchestrator probes separate questions that a single HEALTHCHECK blends together. Each probe type triggers a different action, which is what makes them operationally useful.

  • Liveness: asks whether the process is stuck. A failure typically restarts the container.
  • Readiness: asks whether the instance can serve traffic right now. A failure removes it from service endpoints without restarting it.
  • Startup: gives slow-starting applications extra time before liveness checks begin.

This separation matters because a database outage should not restart every API pod. If your health endpoint checks the database and you wire it to liveness, a temporary database failure can cause a restart storm across the fleet, and the restarts themselves add load to the very dependency that is struggling.

What Should a Health Endpoint Check?

Keep liveness shallow. It should confirm only that the process can respond, for example by returning 200 from an in-memory handler. Readiness can be deeper, verifying that required dependencies are reachable, but even then avoid expensive queries on every probe.

A practical pattern is to expose two paths. One returns quickly and checks nothing external. The other checks critical dependencies with short timeouts. Probe timeouts should be shorter than the probe period so checks do not pile up under load.

livenessProbe:
  httpGet:
    path: /livez
    port: 8080
  periodSeconds: 10
  failureThreshold: 3
readinessProbe:
  httpGet:
    path: /readyz
    port: 8080
  periodSeconds: 5
  timeoutSeconds: 2

Common Pitfalls With Container Health Checks

  • Using curl in a HEALTHCHECK when the image does not include it, which marks a healthy container as unhealthy.
  • Setting the interval too aggressively, which adds load and noise.
  • Skipping start-period or startup probes, so slow boots get killed during initialization.
  • Returning 200 even when the application is shutting down, which keeps traffic flowing to a draining instance.

For minimal images without a shell, build a tiny health binary into the image or rely on orchestrator HTTP probes, which run outside the container. Also remember that a health check is code you must maintain: test it, version it with the application, and make sure it fails when the service is genuinely broken, not only when the process has crashed.

Frequently Asked Questions

Should I use both HEALTHCHECK and Kubernetes probes?

You can, but Kubernetes uses its own probes and generally ignores the image HEALTHCHECK. Keep HEALTHCHECK for Compose and local workflows, and define probes in your manifests for production.

Does an unhealthy Docker container restart automatically?

Not on plain Docker Engine. A restart policy reacts to process exit, not to unhealthy status. Orchestrators can add that behavior, so check your platform documentation.

Should liveness probes check the database?

Usually no. A dependency outage would restart healthy application instances and make recovery slower. Put dependency checks in readiness instead.

How often should a health check run?

Every 5 to 30 seconds is common. Choose an interval that detects failure quickly enough without adding meaningful load, and pair it with a sensible failure threshold.

Summary

HEALTHCHECK reports status, while orchestrator probes drive restarts and traffic routing. Keep liveness shallow, make readiness dependency-aware, use startup probes for slow boots, and avoid wiring external dependencies into liveness. Confirm exact behavior in the documentation for your Docker or orchestrator version.