Skip to main content
RunBook Academy

← All break/fix scenarios in Docker & Containers

beginnerNetworking~15 min

Break/Fix 2: Database connection refused from application

Reported symptoms

  • Application returns 500 errors.
  • Logs show `connection refused` or `dial tcp: lookup db: no such host`.
  • The database container is running.
  • Restarting the application container does not help.

Evidence

  • · docker logs shows connection refused errors
  • · docker exec api sh -c "getent hosts db" returns nothing
Diagnosis and resolutionclick to reveal

Root cause

The application and database containers are on different Compose networks, or the database container is on the default bridge network (which does not support DNS-based service discovery), or the application is using localhost instead of the service name.

Remediation

Put both containers on the same user-defined network in compose.yml. Use the service name (not localhost) in DATABASE_URL. Update the connection string and docker compose up -d.

Verification

DNS resolves (docker exec api getent hosts db returns the database IP). Network connectivity works (docker exec api nc -zv db 5432 succeeds). Application works (the 500 errors are gone).

Prevention

Always define user-defined networks in compose.yml. Use service names as hostnames everywhere. Document the network layout in the runbook.

Reported symptoms

  • Application returns 500 errors.
  • Logs show connection refused or dial tcp: lookup db: no such host.
  • The database container is running.
  • Restarting the application container does not help.

Evidence provided

$ docker ps
CONTAINER ID   STATUS    NAMES
abc123def456   Up        api
def789ghi012   Up        db

$ docker logs api --tail 20
2026-08-08T13:45:23Z ERROR: could not connect to server: Connection refused
        Is the server running on host "db" and accepting TCP/IP connections on port 5432?

$ docker exec api sh -c "getent hosts db"
# (no output)

Root cause

The application and database containers are on different Compose networks, or the database container is on the default bridge network (which does not support DNS-based service discovery), or the application is using localhost instead of the service name.

Diagnosis

  1. Check the network configuration.
  2. docker inspect api --format "{{.NetworkSettings.Networks}}"
  3. docker inspect db --format "{{.NetworkSettings.Networks}}"
  4. Confirm both containers are on the same user-defined bridge network.
  5. Check DNS resolution from the application container.
  6. docker exec api sh -c "getent hosts db"
  7. If empty, DNS is broken. The container is not on the right network.
  8. Check the database container's exposed port.
  9. docker inspect db --format "{{.NetworkSettings.Ports}}"
  10. Confirm port 5432 is exposed.
  11. Check the application's connection string.
  12. docker exec api env | grep -i db
  13. Confirm it points to the service name, not localhost or an IP.

Resolution

If the containers are on different networks:

services:
  api:
    networks: [app-net, db-net]
  db:
    networks: [db-net]

If the database is on the default bridge:

services:
  api:
    networks: [app-net]
  db:
    networks: [app-net]

If the connection string is wrong:

services:
  api:
    environment:
      DATABASE_URL: postgres://app:secret@db:5432/app

Verification

  1. DNS resolves. docker exec api getent hosts db returns the database IP.
  2. Network connectivity. docker exec api nc -zv db 5432 succeeds.
  3. Application works. The 500 errors are gone; requests succeed.