mediumIntermediateSymptom-first#networking#localhost#host-gateway#bridge

Container cannot reach host services — localhost vs host.docker.internal

curl localhost inside container returns connection refused

Likely source:connectivityconfiguration

Focused incident mode — strips away everything but this runbook.

Symptoms

  • curl localhost inside container returns connection refused
  • Application inside container cannot reach a database on the host
  • Connection to host port works from outside Docker but not from within

localhost inside a bridge-mode container is the container's own loopback. Always use the gateway IP or host.docker.internal alias to reach the host.

Evidence to grab

Collect these artifacts before you change anything — they prove (or rule out) each cause.

  • Container network mode

    docker inspect <CONTAINER> --format='{{.HostConfig.NetworkMode}}'
  • Host IP from container

    docker exec <CONTAINER> ip route show default

Diagnostic flow

Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.

Guided decision tree is ready.

Steps with commands, expected output, and pass/fail branches.

Ranked root causes

Evidence checklist

  • Container uses bridge network (default)
  • curl localhost inside container connects to 127.0.0.1 (loopback inside container)
  • Host service listens on 0.0.0.0 but is on the host network

Confirm before fixing

docker exec <CONTAINER> ping -c1 127.0.0.1 && docker exec <CONTAINER> ping -c1 172.17.0.1
READ

Compare localhost vs gateway reachability

Fix

docker run --add-host=host.docker.internal:host-gateway <IMAGE>
CHANGE

Use host.docker.internal to reach the host

Resolution runbook

Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.

1
docker inspect <CONTAINER> --format='NetworkMode: {{.HostConfig.NetworkMode}}'
READ

Check network mode

2
docker inspect <CONTAINER> --format='{{(index .NetworkSettings.Networks "bridge").Gateway}}'
READ

Find the host gateway IP

3
docker exec <CONTAINER> sh -c 'wget -qO- http://172.17.0.1:<HOST_PORT>/ || echo FAIL'
READ

Test host reachability via gateway

4
docker run --add-host=host.docker.internal:host-gateway <IMAGE>
CHANGE

Use host.docker.internal alias to reach the host

Prevention

  • Document that containers must never assume localhost refers to the host.
  • Use --add-host=host.docker.internal:host-gateway for all host-dependent containers.
  • Bind host services to 0.0.0.0 when containers need access (and use firewall rules for security).
  • Prefer explicit service-to-service discovery over host-dependency.

Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.