depends_on in Docker Compose only waits for the container to start — not for the service inside it to be ready. Your app starts before the database is accepting connections.
What causes this error
depends_on checks that the container is running, not that PostgreSQL/MySQL/Redis is ready to accept connections. Your app tries to connect immediately and fails.
Fix 1: Use depends_on with condition (Compose v2)
services:
db:
image: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
app:
build: .
depends_on:
db:
condition: service_healthy
This waits until the healthcheck passes before starting your app.
Fix 2: Add retry logic in your app
// Retry database connection with backoff
async function connectWithRetry(maxRetries = 10) {
for (let i = 0; i < maxRetries; i++) {
try {
await db.connect();
console.log("Database connected");
return;
} catch (err) {
console.log(`Retry ${i + 1}/${maxRetries}...`);
await new Promise(r => setTimeout(r, 2000));
}
}
throw new Error("Could not connect to database");
}
Fix 3: Use wait-for-it script
app:
command: ["./wait-for-it.sh", "db:5432", "--", "node", "app.js"]
Download wait-for-it.sh from github.com/vishnubob/wait-for-it.
Best practice
Use both: healthchecks in Compose AND retry logic in your app. The healthcheck handles startup ordering. The retry logic handles runtime reconnection.
Related: Docker Compose cheat sheet · Docker cheat sheet · Docker Compose vs Kubernetes · Docker vs Kubernetes