Reach a host service from a Docker container—and prove where it fails
Inside a container, localhost means the container itself. Map the host gateway correctly, check the host binding and test DNS, TCP and HTTP as separate layers.
Your application works at http://localhost:8000 on the host, but a container gets “connection refused.” Nothing mysterious happened: network namespaces changed what localhost means. Inside the container, 127.0.0.1 is the container’s own loopback interface—not the host’s.
Prove the host service before changing Docker
ss -ltnp | grep ':8000'
curl -v http://127.0.0.1:8000/health
Read the listening address. A service bound only to 127.0.0.1:8000 accepts host-loopback traffic and may reject traffic arriving through a bridge gateway. If container access is intended, bind the service to an appropriate host interface, commonly 0.0.0.0 or the bridge address, and enforce exposure with the firewall. Do not widen a production listener without reviewing the security boundary.
Docker Desktop: use the provided DNS name
docker run --rm curlimages/curl:latest -v http://host.docker.internal:8000/health
Docker Desktop provides host.docker.internal for reaching the host-side environment. It is preferable to baking a changing private IP into application configuration.
Docker Engine on Linux: map the host gateway
docker run --rm --add-host host.docker.internal:host-gateway curlimages/curl:latest -v http://host.docker.internal:8000/health
Docker’s daemon documentation defines host-gateway as a special value resolved to addresses on the host; by default it uses the default bridge gateway. For Compose:
services:
app:
image: example/app:1.4
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
API_BASE_URL: "http://host.docker.internal:8000"
Recreate the container after changing Compose configuration, then confirm the injected mapping:
docker compose up -d --force-recreate app
docker compose exec app getent hosts host.docker.internal
docker compose exec app cat /etc/hosts
Test one network layer at a time
# 1. Name resolution
getent hosts host.docker.internal
# 2. TCP reachability
nc -vz host.docker.internal 8000
# 3. HTTP exchange
curl -sv --connect-timeout 3 http://host.docker.internal:8000/health
| Result | Likely boundary | Next check |
|---|---|---|
| Name not found | Host mapping or container DNS | Inspect extra_hosts and recreate the container |
| Connection refused | No listener on that address/port | Inspect host binding with ss |
| Timeout | Firewall, route or filtered traffic | Trace rules and packets on the host |
| HTTP 401/403 | Network succeeded; application rejected request | Check credentials and Host header |
When host networking is appropriate
On supported Linux deployments, --network host places the container in the host network namespace, so host loopback semantics differ from bridge mode:
docker run --rm --network host curlimages/curl:latest -v http://127.0.0.1:8000/health
This removes network isolation and can create port collisions. It is not the universal “fix”; choose it only when the architecture calls for host networking and its security implications are understood.
A service-to-service container should usually use a Docker network
If the dependency can run in Compose, address it by service name rather than routing out to the host:
services:
app:
image: example/app:1.4
environment:
API_BASE_URL: "http://api:8000"
api:
image: example/api:2.1
expose:
- "8000"
Compose DNS resolves api on the shared network. This keeps the dependency explicit, portable and separate from the host’s incidental network state.
Close the investigation
Record the container image, network mode, resolved gateway, host listening address and exact curl result. A successful ping is not enough; many services or environments do not answer ICMP, and ping does not prove that the required TCP port or application route works.
“Localhost” names a network namespace, not the physical machine sitting in front of you.
Sources: the solved Stack Overflow question (question by Phil; accepted answer by Thomasleveil, CC BY-SA), Docker’s host-gateway documentation, and Compose networking documentation.
Primary source: Review the official reference ↗