Wait for a dependency to become healthy in Docker Compose
Use health-based startup conditions, validate the probe itself, and keep application retries for failures after startup.
Use the long form of depends_on with condition: service_healthy when a service should wait for a dependency's health check. The short form, depends_on: [db], controls startup order but does not wait for database readiness—even in current Compose.
Add a meaningful health check
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:?Set a database password}"
POSTGRES_DB: mydb
volumes:
- pg-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U postgres -d mydb"]
interval: 5s
timeout: 3s
retries: 10
start_period: 20s
app:
build: .
depends_on:
db:
condition: service_healthy
volumes:
pg-data:
The PostgreSQL 16 volume target is intentional; check image layout when changing major versions. This probe uses TCP loopback so it does not mistake the official image's temporary socket-only initialization server for its final TCP listener.
A successful health-check execution can make the container healthy. retries counts consecutive failures before an unhealthy state; it does not require ten consecutive successes. start_period grants initialization time for failure accounting, not a fixed minimum delay before success is accepted.
pg_isready checks whether PostgreSQL accepts connections, not whether your application's credentials, schema, or migrations work. Add an appropriate application-level check when those conditions define readiness.
Choose the condition
| Condition | What Compose waits for |
|---|---|
service_started |
Dependency started |
service_healthy |
Dependency reports healthy |
service_completed_successfully |
A one-off dependency exits successfully |
For migrations, define a separate migrate service that waits for a healthy database and runs the migration command. Let the application depend on migrate with service_completed_successfully. Avoid running competing migrations in every application replica. A successful migration container must represent the intended current deployment, not an unrelated stale run.
Write probes with the right execution mode
An exec-form health check such as ["CMD", "redis-cli", "ping"] runs directly. It does not expand $VARIABLE arguments. For shell expansion, use CMD-SHELL and escape Compose interpolation as $$VARIABLE where appropriate.
For example, an HTTP image containing curl might use:
healthcheck:
test: ["CMD", "curl", "--fail", "--silent", "http://127.0.0.1:8080/health"]
interval: 10s
timeout: 3s
retries: 3
A MySQL mysqladmin ping can report server availability even when authentication is rejected; it is not a credential-validation probe. Redis checks also need appropriate authentication and response validation for the deployment. Ensure the probe executable exists in the image and avoid exposing passwords in process arguments.
FAQ
Does health failure restart the container?
A Docker health check changes health status. It does not by itself restart an unhealthy container. Restart policies respond to process exit, and a Compose dependency condition does not continuously stop or restart every dependent whenever health changes.
Do I still need retries?
Yes. Dependencies can fail after startup. Use bounded startup retries and suitable runtime reconnection behavior; test both delayed readiness and a later outage.
Does shutdown follow the dependency graph?
Compose stops/removes dependents before their dependencies in its managed lifecycle. Applications still need graceful shutdown behavior. These Compose conditions should not be assumed to work identically with docker stack deploy or another orchestrator.
Record readiness and first-connection timing. Once configured, Guance container collection can help correlate the service logs, but a healthy probe remains only as meaningful as its test.
See Compose startup order, health checks, and pg_isready.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan