Docker Fundamentals · Module 10 of 12

Health, resources and observability

Operate containers with logs, health checks and resource awareness instead of assuming a running process is a healthy service.

Learning objectives

By the end of this module, you should be able to:

  • Differentiate container running state from application health.
  • Use logs, stats and inspect during diagnosis.
  • Explain why CPU/memory constraints matter on shared hosts.

Running is not the same as ready

A container can have a running main process while the application inside is unable to serve requests. Health checks provide an application-aware signal by periodically running a command and recording healthy/unhealthy state.

Observe from multiple angles

docker logs shows application output, docker stats shows live resource consumption, docker inspect shows configured limits/state, and host monitoring shows the wider system. One signal rarely tells the whole story.

Resources are shared

Containers compete for host CPU, memory, I/O and other kernel resources. Runtime limits can prevent one workload from consuming an unreasonable share of a host, but limits must be sized from real workload behavior and tested.

Worked examples

See the idea in practice.

Add a runtime health check

docker run -d --name healthy-web -p 8080:80 \
  --health-cmd='wget -qO- http://127.0.0.1/ >/dev/null || exit 1' \
  --health-interval=10s --health-timeout=3s --health-retries=3 nginx:alpine
  • The health command runs inside the container.
  • The Engine records health separately from basic running state.

Observe resources

docker stats --no-stream
docker inspect healthy-web --format '{{json .State.Health}}'
  • stats provides current resource measurements.
  • inspect exposes recent health-check results.
Hands-on lab

Lab — Diagnose a container with health state

Goal: Run a health-checked service, inspect its status and collect operational evidence before cleanup.

STEP 1

Start health-checked nginx

docker run -d --name health-lab --health-cmd='wget -qO- http://127.0.0.1/ >/dev/null || exit 1' --health-interval=5s --health-timeout=2s --health-retries=3 nginx:alpine
STEP 2

Watch health transition

for i in 1 2 3 4 5; do docker inspect health-lab --format '{{.State.Status}} {{if .State.Health}}{{.State.Health.Status}}{{end}}'; sleep 2; done
STEP 3

Collect logs and stats

docker logs --tail 20 health-lab
docker stats --no-stream health-lab
STEP 4

Clean up

docker rm -f health-lab

Verify

  • Container state and health are visible as separate concepts.
  • You can collect logs and one-shot resource data without entering the container.

Expected outcome

  • Health eventually reports healthy if nginx starts normally.

If it fails

  • A minimal image may not contain the tool used by your health command; choose a check available in the image or add an appropriate application-native check.
  • A health check that is too aggressive can create noisy false failures during startup.
Real-world connection

Schedulers and load balancers need reliable health/readiness signals to decide whether traffic should reach a workload.

Avoid these traps

Common mistakes

  • Treating running as proof of application correctness.
  • Writing a health check that tests only whether a process exists while ignoring the real service endpoint.
  • Ignoring host capacity when setting no resource controls for noisy workloads.
Knowledge check

Can you explain it without looking back?

Open each answer only after you have tried to answer the question yourself.

1What does a health check add beyond docker ps running state?

It tests an application-specific condition and records healthy/unhealthy state separately from whether the main process exists.

2Which command provides live container resource usage?

docker stats.

3Why can an overly strict health check be harmful?

It can mark a correctly starting or temporarily slow service unhealthy and cause unnecessary recovery actions in higher-level systems.