All guides

LEARN \u00b7 DEBUGGING GUIDE

Docker container cannot connect to localhost: how to debug it

Your containerised app tries to connect to a database on `localhost` and gets 'connection refused'. The database is running fine on your machine. The container simply has a different `localhost`.

BeginnerDocker/deployment debugging

What this usually means

Inside a Docker container, `localhost` means the container itself, not your host machine. When your app code calls `localhost:5432`, it is looking for a service running inside the same container. Unless you run your database inside that container, nothing is listening there. Docker containers run on an isolated network. To reach a service on the host, you need to use the special DNS name `host.docker.internal` (macOS/Windows) or the host's IP on the Docker bridge network (Linux).

( 01 )Fast diagnosis

The first ten minutes \u2014 establish facts before touching code.

  • 1Confirm the service is running on the host: `curl localhost:5432` or `nc -zv localhost 5432` from outside Docker.
  • 2Inside the container, try reaching the host: `docker exec <container> ping host.docker.internal`. If it resolves, use that hostname.
  • 3Check the container's network mode. `docker run --network host` removes network isolation but has trade-offs.
  • 4If using docker-compose, check the service name. Containers in the same compose network reach each other by service name, not localhost.
  • 5Verify the service is listening on `0.0.0.0` not just `127.0.0.1`. A service bound to 127.0.0.1 only accepts connections from the same machine.
( 02 )Where to look

The specific files, logs, configs, and dashboards that usually own this bug.

  • searchDocker run command or docker-compose.yml — network mode and port mappings
  • searchThe host service's bind address (`netstat -an`, `ss -tlnp`) — must be 0.0.0.0 to accept Docker connections
  • searchContainer shell: `docker exec -it <container> sh` — test connectivity with curl, ping, nc
  • searchDocker networking docs — `host.docker.internal` availability per platform
  • searchFirewall rules — host firewall may block Docker bridge network traffic
( 03 )Common root causes

Practical causes, not theory. These are the things you will actually find.

  • warningService on host is bound to 127.0.0.1 only, rejecting Docker bridge network connections
  • warningUsing `localhost` or `127.0.0.1` in connection strings inside the container
  • warning`host.docker.internal` not available on Linux (requires Docker 20.10+ with `--add-host` flag)
  • warningDocker container is on a different network than expected (custom bridge vs default bridge)
  • warningHost firewall blocks the Docker bridge IP range
  • warningPort mapping is wrong or missing in `docker run -p` or compose `ports` section
( 04 )Fix patterns

Concrete fix directions. Pick the one that matches your root cause.

  • buildUse `host.docker.internal` instead of `localhost` for host services (macOS/Windows)
  • buildOn Linux, add `--add-host=host.docker.internal:host-gateway` to `docker run` or use the host's Docker bridge IP
  • buildIn docker-compose, reference other services by their compose service name, not IP or localhost
  • buildEnsure the host service binds to `0.0.0.0` or the Docker bridge interface, not only 127.0.0.1
  • buildFor production, run dependent services (DB, cache) as containers in the same compose network — do not rely on host networking
( 05 )How to verify

A fix you cannot prove is a guess. Close the loop.

  • verifiedFrom inside the container, run `curl host.docker.internal:<port>` or `nc -zv host.docker.internal <port>`. Confirm connection.
  • verifiedCheck the host service logs show an incoming connection from the Docker container.
  • verifiedRun the full stack with docker-compose and verify all container-to-container connections work.
  • verifiedTest from a second container on the same Docker network to rule out host-level firewall issues.
  • verifiedDocument the networking setup so the next developer does not spend an hour on this again.
( 06 )Mistakes to avoid

Things that make this bug worse or harder to find.

  • warningUsing `--network host` as a permanent fix — it breaks container isolation and portability
  • warningHardcoding the host's IP address instead of using DNS names or compose service names
  • warningAssuming `host.docker.internal` works on all Linux distributions without extra configuration
  • warningForgetting that each container has its own loopback interface
  • warningNot checking the service bind address before debugging Docker networking