CodePark/ questions / Docker Compose
START PRACTICINGPRACTICE
Backend question · Docker › Docker Compose

The API crashes on startup because Postgres isn't ready yet, even with depends_on: [db]. Why, and how does this file fix it?

services:
  api:
    build: .
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres:16
    environment: { POSTGRES_PASSWORD: example }
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 10

Plain depends_on only waits for the db container to start. It does not wait for Postgres inside the container to accept connections. Postgres needs a few seconds to start up, so the API connects too early and fails.

This file fixes it in two steps:

  • It adds a healthcheck that runs pg_isready every 5 seconds. A healthcheck is a command Docker runs to test if the service works.
  • condition: service_healthy makes Compose wait until that check passes. Only then does it start api.

There are other conditions too:

  • service_started is the default.
  • service_completed_successfully waits for a service to finish without errors. This is useful for a one-off job, like a database migration.

This only helps when Compose starts the services. Later, the database can still restart or drop connections. So the app should also retry its connection with backoff (waiting longer between each try). It should not assume the database is always up.

  • depends_on alone waits for the container to start, not for it to be ready.
  • Add a healthcheck to the service you depend on.
  • condition: service_healthy waits for the healthcheck to pass.
  • Use service_completed_successfully for one-off jobs like migrations.
  • The app should still retry its database connections.