Docker Compose — Condition: service_healthy

1 minute read

The condition: service_healthy option makes depends_on wait until a dependency’s health check passes — solving the readiness problem.

The Complete Pattern

services:
  api:
    image: node:20-alpine
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_healthy

  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5
      start_period: 10s

  cache:
    image: redis:7
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5

What Happens

0s    db starts, cache starts
0-10s db: start_period (grace period)
10s   db: first health check → PASS ✓
5s    cache: first health check → PASS ✓
      Both healthy → api starts

Available Conditions

Condition Waits For
service_started Container started (default)
service_healthy Health check passes
service_completed_successfully Container exits with code 0

service_completed_successfully

Useful for init containers (migrations, seed data):

services:
  migrate:
    image: myapp:latest
    command: npm run migrate

  api:
    image: myapp:latest
    depends_on:
      migrate:
        condition: service_completed_successfully
      db:
        condition: service_healthy

Compose waits for migrate to finish successfully before starting api.

Full Real-World Example

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    depends_on:
      api:
        condition: service_healthy

  api:
    image: node:20-alpine
    command: node server.js
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 15s
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_healthy

  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5
      start_period: 10s

  cache:
    image: redis:7
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5

Startup order: db + cache (parallel, wait for healthy) → api (wait for healthy) → web

Summary

Condition Use Case
service_started Just need container running
service_healthy Need application ready
service_completed_successfully Need init task done

Quick Reference

Item Detail
service_healthy Wait for health check to pass
service_started Wait for container start only
service_completed_successfully Wait for exit code 0
Requires healthcheck: on the dependency
Pattern depends_on: + condition: + healthcheck: