Docker Compose Container Can't Connect to Database — Fix (2026)
Getting 'connection refused' between Docker Compose containers? Here are the 7 most common causes and how to fix each one, with working examples.
"Connection refused" between Docker Compose services is one of the most common errors beginners hit. Your app container starts fine but can't reach the database. Here's every cause and fix.
Quick Diagnosis
# Check if all containers are running
docker compose ps
# Check container logs
docker compose logs db
docker compose logs app
# Test connectivity from inside app container
docker compose exec app ping db
docker compose exec app nc -zv db 5432Cause 1: Wrong Hostname — Using localhost Instead of Service Name
The most common mistake. In Docker Compose, containers don't connect via localhost — they use the service name as the hostname.
services:
db:
image: postgres:15
app:
image: my-appYour app must use db as the hostname, not localhost:
# WRONG
DATABASE_URL = "postgresql://user:pass@localhost:5432/mydb"
# CORRECT — use the service name
DATABASE_URL = "postgresql://user:pass@db:5432/mydb"# In docker-compose.yml
services:
app:
environment:
DATABASE_URL: "postgresql://user:pass@db:5432/mydb"
# ↑ service nameCause 2: App Starts Before DB Is Ready
Docker Compose depends_on only waits for the container to start, not for the database inside to be ready to accept connections. PostgreSQL takes 2-5 seconds to initialize.
Symptom:
app_1 | Error: connect ECONNREFUSED 172.18.0.2:5432
db_1 | LOG: database system is ready to accept connections
# (db becomes ready after app already crashed)
Fix 1: Use healthcheck with depends_on condition
services:
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
start_period: 10s
app:
image: my-app
depends_on:
db:
condition: service_healthy # ← wait for healthcheck to passFix 2: Retry logic in your app
import time
import psycopg2
def connect_with_retry(max_retries=10, delay=2):
for attempt in range(max_retries):
try:
conn = psycopg2.connect(os.environ["DATABASE_URL"])
print("Connected to database")
return conn
except psycopg2.OperationalError:
print(f"DB not ready, retry {attempt+1}/{max_retries}...")
time.sleep(delay)
raise Exception("Could not connect to database")Cause 3: Not on the Same Network
By default, all services in a docker-compose.yml share one network. But if you have multiple Compose files or custom network configs, services might be isolated.
Check networks:
docker network ls
docker inspect <container_id> | grep -A 10 NetworksFix: Explicitly put services on the same network:
services:
db:
image: postgres:15
networks:
- backend
app:
image: my-app
networks:
- backend
networks:
backend:
driver: bridgeCause 4: Wrong Port
The container port ≠ the published host port.
services:
db:
image: postgres:15
ports:
- "5433:5432" # host:container- From your laptop: connect to
localhost:5433 - From another container: connect to
db:5432(container port, not host port)
# app container env var
DATABASE_URL: "postgresql://user:pass@db:5432/mydb"
# ↑ 5432, NOT 5433Cause 5: Database Didn't Initialize Properly
PostgreSQL silently fails to initialize if the data directory already has data with a different password.
# Check db logs for initialization errors
docker compose logs db | head -50
# Common error:
# FATAL: data directory "/var/lib/postgresql/data" has wrong ownership
# FATAL: password authentication failed for user "postgres"Fix: Remove the volume and restart
docker compose down -v # WARNING: deletes all data
docker compose up -dIf you want to keep data, check volume permissions:
docker compose exec db ls -la /var/lib/postgresql/Cause 6: App Connecting to Host, Not Container
If your app is running on the host machine (not in Docker) but the DB is in Docker:
# Expose DB port to host
services:
db:
ports:
- "5432:5432" # now reachable from hostAnd from host: localhost:5432 works. But from inside another container, you need db:5432.
Cause 7: Environment Variables Not Set Correctly
YAML indentation errors or wrong env var names:
# WRONG — environment is a sibling of image, not inside
services:
app:
image: my-app
environment: # ← wrong indentation
DB_HOST: db
# CORRECT
services:
app:
image: my-app
environment: # ← under app
DB_HOST: dbCheck env vars are actually set:
docker compose exec app env | grep DBFull Working Example
# docker-compose.yml
services:
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: appuser
POSTGRES_PASSWORD: secret123
POSTGRES_DB: myapp
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U appuser -d myapp"]
interval: 5s
timeout: 5s
retries: 10
start_period: 15s
networks:
- app-network
app:
build: .
environment:
DATABASE_URL: "postgresql://appuser:secret123@db:5432/myapp"
depends_on:
db:
condition: service_healthy
ports:
- "3000:3000"
networks:
- app-network
volumes:
db-data:
networks:
app-network:Debug Checklist
# 1. Are all containers running?
docker compose ps
# 2. Can app reach db by hostname?
docker compose exec app ping -c 3 db
# 3. Is the port actually open?
docker compose exec app nc -zv db 5432
# 4. What do the db logs say?
docker compose logs db --tail=50
# 5. Is the env var set correctly in app?
docker compose exec app env | grep -i db
# 6. What network are they on?
docker compose exec app cat /etc/hostsResources
- KodeKloud Docker Course — hands-on Docker Compose labs
- Docker Compose Docs — official networking guide
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
AWS ECS Task Keeps Stopping — How to Fix It (2026)
Your ECS task starts and then immediately stops or keeps restarting. Here's every reason this happens and how to debug and fix it.
Why Your Docker Container Keeps Restarting (and How to Fix It)
CrashLoopBackOff, OOMKilled, exit code 1, exit code 137 — Docker containers restart for specific, diagnosable reasons. Here is how to identify the exact cause and fix it in minutes.
Kubernetes OOMKilled: How I Fixed Out of Memory Errors in Production
OOMKilled crashes killing your pods? Here's the real cause, how to diagnose it fast, and the exact steps to fix it without breaking production.