Skip to content

use-depends-on-condition

docker compose depends_on doesn't wait for the database to be ready. Using condition: service_healthy to fix startup race conditions.

On this page

Short-form depends_on: [db] controls start order, not readiness: Compose starts the app the instant the database container exists — several seconds before the database inside it accepts connections. The app's first connection attempt fails, and you're in crash-loop-until-the-race-resolves territory. This rule flags short-form depends_on lists.

What the rule catches

compose.yaml — app starts before postgres accepts connections
services:
  web:
    build: .
    depends_on:
      - db

  db:
    image: postgres:17-alpine

Scanning this file reports:

ℹ INFO [docker-doctor/use-depends-on-condition]
  Service 'web' uses shorthand depends_on list. This only checks if containers are started, not if they are ready/healthy.

Why it matters

"Web can't connect to postgres on docker compose up, but works after a restart" is one of the most-asked Compose questions, and this race is the answer. The fix is built in: give the dependency a healthcheck that verifies real readiness, and make the dependent wait with condition: service_healthy. Compose then holds the app until the database has proven it accepts connections — no sleep 10, no wait-for-it scripts, no retry-loop scaffolding around startup.

How to fix it

Instead of a simple service list, use depends_on: { dependency: { condition: service_healthy } } to ensure dependencies are fully ready before starting.

compose.yaml — app waits until postgres is actually ready
services:
  web:
    build: .
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:17-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5

The conditions: service_healthy (wait for the healthcheck to pass — what you want for databases and queues), service_started (the old short-form behavior), and service_completed_successfully (wait for a one-shot task like a migration job to exit 0 — handy for migrate → app sequences). Startup ordering complements, but doesn't replace, connection retry logic in the app: services can still become unready later.

Rule details

  • Rule keydocker-doctor/use-depends-on-condition
  • Category — Compose
  • Default severityinfo
  • Applies to — Docker Compose files

Explain this rule from the CLI:

npx @docker-doctor/cli@latest rules explain docker-doctor/use-depends-on-condition

Change its severity — or turn it off — in your config file:

// docker-doctor.config.ts
export default {
  rules: {
    "docker-doctor/use-depends-on-condition": "off",
  },
};

Severity affects the health score: error findings cost more points than warning, and info costs the least.