Skip to main content

Wait for database readiness in Docker Compose

2026-11-11 16:36:34.730811+00:00
Wait for database readiness in Docker Compose

A web container can start while PostgreSQL is still initializing its data directory. If the application opens its first connection during that interval, an otherwise valid release can fail with a connection error. Give the database a readiness check and make the application's initial startup depend on that check.

Declare the startup condition

This illustrative Compose fragment assumes a disposable PostgreSQL service. It omits credentials and application details; supply those through the deployment's existing secret mechanism before running it.

services:
  db:
    image: postgres:18
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
      interval: 5s
      timeout: 3s
      retries: 12
      start_period: 20s
  web:
    build: .
    depends_on:
      db:
        condition: service_healthy

The doubled dollar sign leaves expansion to the container's shell. Check that the database's environment defines the referenced user and database. A misspelled value can keep a healthy server marked unhealthy. Docker documents service_healthy as the dependency condition that waits for the configured healthcheck.

A successful database healthcheck permits initial web startup; later connection failures still need application handling.

Observe a cold start

Use a throwaway environment with an empty database volume. Inspect docker compose ps and the database logs while startup proceeds. Confirm that the web service waits, then starts after the health status changes. Repeat with an invalid database configuration and verify that the application never reports a successful startup.

Record the installed Compose version and the elapsed startup behavior. The fragment above was reviewed as configuration, without a Docker execution in this authoring environment. An operator should also validate the completed file with docker compose config before testing it.

Handle a later disconnect

The dependency condition applies to startup ordering. A database can become unavailable after the web process has begun serving requests. The application still needs bounded connection timeouts and a deliberate response to lost connections. For example, a readiness route can report unavailable while ordinary requests return a controlled service error.

Avoid restarting every application worker whenever a shared database is briefly down. That can discard useful diagnostics and add reconnection pressure. Test database recovery separately: interrupt the disposable service, observe failures, restore it, and confirm whether existing workers recover without manual intervention. A passing pg_isready check also does not prove that migrations or an application-specific query will succeed.

Reference: Docker Compose startup order. Related deployment writing is available in the engineering blog.