Is the app actually up?
A running container is not proof of a working app: the process can be alive while the app inside is deadlocked or can't reach its database. Lesson 5-2 hit this as "started is not ready". Every platform from lesson 9-1 therefore asks your app the same question on repeat: are you healthy?
The convention: your app exposes a health endpoint, a URL like /health that answers 200 OK quickly, after checking its own vitals (can I reach the DB?). Then you declare it, here in compose:
app:
build: .
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 10s
retries: 3
restart: unless-stoppedtest: the probe command, run inside the container.curl -fexits non-zero on HTTP errors, and yes, it is exit codes again (lesson 7-1)interval: 10s,retries: 3: probe every 10 seconds, and only after 3 consecutive failures mark the containerunhealthyrestart: unless-stopped: have Docker restart the container if it dies, so a crash at 3am doesn't wait for you
Health checks power everything else
Once the platform can tell healthy from unhealthy, the patterns from earlier lessons click together:
- Compose startup order (lesson 5-2):
depends_onwithcondition: service_healthywaits for the db's healthcheck to pass before starting the app - Rolling and blue-green deploys (lesson 8-3): the load balancer only shifts traffic to new containers once they probe healthy, and an unhealthy new version aborts the rollout automatically
- Self-healing: restart policies and orchestrators replace unhealthy containers without a human
One subtlety: platforms retry probes before declaring death, because one slow response might be a blip. The next block simulates that retry loop.
Code exercise · bash
Run this simulated health prober. The service needs a moment to warm up, so the first probes fail and the prober retries instead of declaring the container dead on attempt 1.
Quiz
During a rolling deploy, the new version's containers never pass their health checks. What should a well-configured platform do?
Problem
In compose, depends_on can wait for a service to be genuinely ready, not just started. Fill the blank: condition: service_________