Docker Tutorial · Docker Compose · Lesson 20 of 26

Startup Order and Healthchecks

depends_on only orders startup; use healthchecks and condition: service_healthy to wait until a service is ready.

Create a free account to save this page, take notes and track your progress. Sign in

Started is not ready

depends_on: [db] starts db before api, but a database container that has started may need several seconds before it accepts connections. Add a healthcheck and wait for it:

services:
  db:
    image: postgres:18-alpine
    environment: { POSTGRES_PASSWORD: example }
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 2s
      retries: 15
  api:
    build: .
    depends_on:
      db:
        condition: service_healthy

Applications should still retry connections on their own: databases restart in production too.

Wait for a healthy database before running migrations
trap 'docker compose -p rc-health down -v > /dev/null 2>&1' EXIT
cat > compose.yaml <<'EOF'
services:
  db:
    image: postgres:18-alpine
    environment:
      POSTGRES_PASSWORD: example
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 1s
      retries: 30
  migrate:
    image: postgres:18-alpine
    environment:
      PGPASSWORD: example
    command: ["psql", "-h", "db", "-U", "postgres", "-tAc", "select 'connected to PostgreSQL ' || current_setting('server_version_num')::int / 10000"]
    depends_on:
      db:
        condition: service_healthy
EOF
set -e
docker compose -p rc-health run --rm migrate 2>/dev/null
docker compose -p rc-health ps db --format '{{.Service}} health: {{.Health}}'

Output

connected to PostgreSQL 18
db health: healthy

Run this on your computer — see “Get Started” for setup.

Test yourself

What does depends_on without a condition guarantee?

  1. That the database accepts connections
  2. Only that the dependency's container was started first
  3. That ports are published
  4. Nothing
Show answer

Answer: Only that the dependency's container was started first

Use condition: service_healthy with a healthcheck to wait for readiness.

Was this page helpful?