Docker cookbook · Beginner

Make containers cope with dependencies that start slowly

The app crashes when the database isn't ready yet, in Compose and after database restarts.

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

Approach

Use healthchecks with service_healthy for startup order in Compose, and make the application retry connections with backoff, because dependencies also restart in production.

Solution

import time
import psycopg

def connect(dsn, attempts=30):
    delay = 0.5
    for attempt in range(1, attempts + 1):
        try:
            return psycopg.connect(dsn, connect_timeout=3)
        except psycopg.OperationalError as exc:
            if attempt == attempts:
                raise
            print(f"database not ready ({exc.__class__.__name__}), retrying in {delay:.1f}s", flush=True)
            time.sleep(delay)
            delay = min(delay * 2, 5)

Pitfalls

  • Shell wait-for-it scripts as the only protection; they don't help when the database restarts later.
  • Retrying forever without logging, so a misconfiguration looks like a hang.

Variations

  • Connection pools with built-in reconnect and health checks.
  • Readiness endpoints that report "not ready" until dependencies are reachable.

Further reading: Control startup order

Reference: https://docs.docker.com/compose/how-tos/startup-order/

More Docker recipes

Was this page helpful?