Docker Compose — Wait for Container X Before Starting Y

When working with Docker Compose, you often have multiple containers that depend on each other. For example, your application (app) might depend on a database (db). You don’t want your app to start before the database is ready — otherwise, it might fail to connect.

In this guide, we’ll go over how to make one container wait for another before starting in Docker Compose.


1️⃣ The Problem

Docker Compose has a depends_on option that controls startup order, but it only waits until the dependent container has started — not until it’s ready to accept connections.

Example:

services:
  app:
    build: .
    depends_on:
      - db
  db:
    image: postgres:15

In this setup, app will start after db starts, but if Postgres takes a few seconds to initialize, the app may crash.


2️⃣ The Simple Solution — depends_on + Healthchecks

We can combine depends_on with healthchecks to make Compose wait until the service is actually ready.

Example with Postgres + App:

version: '3.9'

services:
  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user"]
      interval: 5s
      timeout: 3s
      retries: 5

  app:
    build: .
    depends_on:
      db:
        condition: service_healthy

How it works:

  • healthcheck runs pg_isready to check if Postgres is accepting connections.
  • depends_on with condition: service_healthy ensures app starts only when the database passes healthcheck.

3️⃣ The Custom Script Approach — wait-for-it or dockerize

Sometimes you need more complex waiting logic, especially for non-standard services.
You can use tools like:

Example using wait-for-it.sh:

  1. Add the script to your project: curl -o wait-for-it.sh https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh chmod +x wait-for-it.sh
  2. Update your Dockerfile to include it.
  3. In docker-compose.yml: app: build: . depends_on: - db entrypoint: ["./wait-for-it.sh", "db:5432", "--", "npm", "start"]

This waits for db:5432 to be reachable before running the main app command.


4️⃣ Which Method Should You Use?

MethodProsCons
depends_on + healthcheckNative Docker feature, no scripts neededHealthcheck syntax can be verbose
wait-for-it.shWorks for any TCP serviceRequires adding extra script
dockerizeRich features (HTTP/TCP wait, templating)Extra binary in your image

📌 Summary

To make one container wait for another in Docker Compose:

  1. Use depends_on with a healthcheck for a clean, native solution.
  2. Use helper scripts (wait-for-it.sh, dockerize) for more flexibility.
  3. Always ensure readiness is about service availability, not just startup order.
Sharing Is Caring:

Leave a Comment