Quick take: Add reliable Docker HEALTHCHECK probes, inspect container health, configure Compose dependencies, and avoid common monitoring mistakes.

Running does not mean healthy

A container can remain running while its application is deadlocked or returning errors. A health check adds a separate starting, healthy, or unhealthy status. Docker records the result, but a standalone unhealthy container is not automatically repaired unless your platform or automation acts on it.

Add a Dockerfile health check

FROM nginx:alpine
RUN apk add --no-cache curl
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD curl --fail --silent http://localhost/health || exit 1

Exit code 0 means success and 1 means unhealthy. Keep the probe fast, deterministic, local, and inexpensive.

Configure Docker Compose

services:
  web:
    build: .
    healthcheck:
      test: ["CMD", "curl", "--fail", "http://localhost/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s
  worker:
    image: my-worker
    depends_on:
      web:
        condition: service_healthy

The start period gives a slow application time to initialize before failures count.

Inspect health failures

docker ps
docker inspect --format='{{json .State.Health}}' my-container
docker events --filter event=health_status
docker logs --tail 100 my-container

Docker stores short probe output in the health state. Return useful diagnostics without secrets or full response bodies.

Design useful probes

Test essential application behavior rather than only checking for a process. Avoid making every remote dependency part of one liveness probe because a shared outage can make an entire fleet unhealthy. Use sensible timeouts and test the recovery path deliberately.

Production implementation workflow

A reliable implementation of Docker container health checks requires more than copying commands. Treat Dockerfile HEALTHCHECK and Compose healthcheck settings as an operated service with ownership, validation, monitoring, and rollback. The objective is to protect containerized applications while avoiding running containers that cannot serve requests and cascading restarts. The following workflow turns a lab configuration into a repeatable production practice.

Plan the change before touching production

Record the owner, affected hosts, maintenance window, rollback trigger, and expected user impact. A short written plan prevents an urgent technical change from becoming an untraceable operational event. For Docker container health checks, collect docker inspect health history, application logs, events, and endpoint latency. Run docker inspect --format='{{json .State.Health}}' my-container where appropriate and compare the result with the recorded baseline. Do not continue merely because the command exited successfully; confirm the expected behavior from the perspective of the workload.

Make the decision visible to the next engineer. Note how the Dockerfile or compose.yaml healthcheck block affects the application health endpoint, which assumption was tested, and what result proves success. This extra context is especially important when addressing running containers that cannot serve requests and cascading restarts, because the safest response depends on service design rather than a universal command.

Establish a clean baseline

Capture the current version, configuration, service state, resource usage, and recent errors. Without a baseline, a later difference may be blamed on the change even when it existed beforehand. For Docker container health checks, collect docker inspect health history, application logs, events, and endpoint latency. Run docker inspect --format='{{json .State.Health}}' my-container where appropriate and compare the result with the recorded baseline. Do not continue merely because the command exited successfully; confirm the expected behavior from the perspective of the workload.

Make the decision visible to the next engineer. Note how the Dockerfile or compose.yaml healthcheck block affects the application health endpoint, which assumption was tested, and what result proves success. This extra context is especially important when addressing running containers that cannot serve requests and cascading restarts, because the safest response depends on service design rather than a universal command.

Use a canary first

Apply the procedure to one representative non-critical host before a fleet rollout. The canary should use the same repositories, network path, data shape, and startup behavior as production. For Docker container health checks, collect docker inspect health history, application logs, events, and endpoint latency. Run docker inspect --format='{{json .State.Health}}' my-container where appropriate and compare the result with the recorded baseline. Do not continue merely because the command exited successfully; confirm the expected behavior from the perspective of the workload.

Make the decision visible to the next engineer. Note how the Dockerfile or compose.yaml healthcheck block affects the application health endpoint, which assumption was tested, and what result proves success. This extra context is especially important when addressing running containers that cannot serve requests and cascading restarts, because the safest response depends on service design rather than a universal command.

Keep configuration reviewable

Store local policy in a clearly named file, document why each non-default value exists, and protect secrets separately. Reviewable configuration is easier to audit, reproduce, and roll back. For Docker container health checks, collect docker inspect health history, application logs, events, and endpoint latency. Run docker inspect --format='{{json .State.Health}}' my-container where appropriate and compare the result with the recorded baseline. Do not continue merely because the command exited successfully; confirm the expected behavior from the perspective of the workload.

Make the decision visible to the next engineer. Note how the Dockerfile or compose.yaml healthcheck block affects the application health endpoint, which assumption was tested, and what result proves success. This extra context is especially important when addressing running containers that cannot serve requests and cascading restarts, because the safest response depends on service design rather than a universal command.

Validate syntax before reload

Use the product's validation command before restarting or reloading a service. Syntax checks catch common quoting, indentation, path, and option errors without creating avoidable downtime. For Docker container health checks, collect docker inspect health history, application logs, events, and endpoint latency. Run docker inspect --format='{{json .State.Health}}' my-container where appropriate and compare the result with the recorded baseline. Do not continue merely because the command exited successfully; confirm the expected behavior from the perspective of the workload.

Make the decision visible to the next engineer. Note how the Dockerfile or compose.yaml healthcheck block affects the application health endpoint, which assumption was tested, and what result proves success. This extra context is especially important when addressing running containers that cannot serve requests and cascading restarts, because the safest response depends on service design rather than a universal command.

Separate availability from correctness

A process that exists is not proof that the service performs useful work. Test the behavior users depend on and distinguish startup, readiness, liveness, and dependency failures. For Docker container health checks, collect docker inspect health history, application logs, events, and endpoint latency. Run docker inspect --format='{{json .State.Health}}' my-container where appropriate and compare the result with the recorded baseline. Do not continue merely because the command exited successfully; confirm the expected behavior from the perspective of the workload.

Make the decision visible to the next engineer. Note how the Dockerfile or compose.yaml healthcheck block affects the application health endpoint, which assumption was tested, and what result proves success. This extra context is especially important when addressing running containers that cannot serve requests and cascading restarts, because the safest response depends on service design rather than a universal command.

Observe the rollout

Watch logs, service state, resource graphs, and application responses during the change. Continue observing after the first success because delayed failures often appear under traffic or scheduled work. For Docker container health checks, collect docker inspect health history, application logs, events, and endpoint latency. Run docker inspect --format='{{json .State.Health}}' my-container where appropriate and compare the result with the recorded baseline. Do not continue merely because the command exited successfully; confirm the expected behavior from the perspective of the workload.

Make the decision visible to the next engineer. Note how the Dockerfile or compose.yaml healthcheck block affects the application health endpoint, which assumption was tested, and what result proves success. This extra context is especially important when addressing running containers that cannot serve requests and cascading restarts, because the safest response depends on service design rather than a universal command.

Define a rollback trigger

Choose measurable conditions that stop the rollout, such as repeated failures, rising latency, missing data, or an unexpected restart. Decide the rollback action before pressure makes the decision harder. For Docker container health checks, collect docker inspect health history, application logs, events, and endpoint latency. Run docker inspect --format='{{json .State.Health}}' my-container where appropriate and compare the result with the recorded baseline. Do not continue merely because the command exited successfully; confirm the expected behavior from the perspective of the workload.

Make the decision visible to the next engineer. Note how the Dockerfile or compose.yaml healthcheck block affects the application health endpoint, which assumption was tested, and what result proves success. This extra context is especially important when addressing running containers that cannot serve requests and cascading restarts, because the safest response depends on service design rather than a universal command.

Automate cautiously

Automation should be idempotent, produce an audit trail, and fail safely. Test both the successful path and the partial-failure path, including what happens when a host is offline or a dependency is unavailable. For Docker container health checks, collect docker inspect health history, application logs, events, and endpoint latency. Run docker inspect --format='{{json .State.Health}}' my-container where appropriate and compare the result with the recorded baseline. Do not continue merely because the command exited successfully; confirm the expected behavior from the perspective of the workload.

Make the decision visible to the next engineer. Note how the Dockerfile or compose.yaml healthcheck block affects the application health endpoint, which assumption was tested, and what result proves success. This extra context is especially important when addressing running containers that cannot serve requests and cascading restarts, because the safest response depends on service design rather than a universal command.

Document the final state

Record the effective configuration, commands used, validation evidence, exceptions, and follow-up work. Good documentation shortens the next maintenance window and supports incident response. For Docker container health checks, collect docker inspect health history, application logs, events, and endpoint latency. Run docker inspect --format='{{json .State.Health}}' my-container where appropriate and compare the result with the recorded baseline. Do not continue merely because the command exited successfully; confirm the expected behavior from the perspective of the workload.

Make the decision visible to the next engineer. Note how the Dockerfile or compose.yaml healthcheck block affects the application health endpoint, which assumption was tested, and what result proves success. This extra context is especially important when addressing running containers that cannot serve requests and cascading restarts, because the safest response depends on service design rather than a universal command.

Security and reliability checklist

Use this checklist before declaring Docker container health checks complete:

  • Limit administrative access and apply least privilege.
  • Keep secrets out of HTML, shell history, logs, metrics labels, and source control.
  • Use supported packages and verify downloads or repository signatures.
  • Restrict network listeners to the hosts that genuinely require access.
  • Back up state and test restoration, not only backup creation.
  • Log configuration changes and retain enough history for investigation.
  • Monitor probe success rate, probe duration, and time spent unhealthy.
  • Patch dependencies and review release notes before major upgrades.
  • Test failure behavior, restart behavior, and the rollback procedure.
  • Assign an owner for alerts and maintenance rather than assuming someone will notice.

A disciplined troubleshooting method

When Docker container health checks fails, begin with scope: one host, one application, one network segment, or the full fleet. Confirm time synchronization, because incorrect clocks make logs and certificates misleading. Check the application health endpoint, then inspect docker inspect health history, application logs, events, and endpoint latency. Work from the user-visible symptom toward the underlying component instead of changing several settings at once.

Form one hypothesis, collect evidence, make one reversible change, and test again. Preserve the original error and command output in the incident record. If rollback restores service, keep investigating in a safe environment; a successful rollback identifies the change boundary but does not automatically explain the root cause.

Ongoing maintenance

Review Docker container health checks at least quarterly and after operating-system, container-engine, application, or monitoring upgrades. Remove obsolete exceptions, verify that alerts still reach an accountable person, and rehearse recovery. Capacity and traffic patterns change, so thresholds that were sensible during installation may later become noisy or dangerously permissive.

The strongest operational signal is not the existence of a configuration file. It is consistent evidence that the service works, failures are detected promptly, responders know what to do, and changes can be reproduced across containerized applications.

Official reference

Commands and defaults were checked against the official documentation. Confirm release-specific details before changing production systems.

Frequently asked questions

Does Docker restart an unhealthy container automatically?+

Health status alone does not guarantee a restart for a standalone container.

Which exit codes should probes use?+

Use 0 for success and 1 for unhealthy; Docker reserves exit code 2.

Should probes call external services?+

Usually prefer a local endpoint to avoid cascading unhealthy states.

Need Linux or DevOps help?

Get practical support for servers, containers, monitoring, and automation.

Hire Me for Your Project