Skip to main content

host.docker.internal on Linux: Why It Fails and the 1-Line Fix (2026)

· 5 min read

host.docker.internal does not exist on Linux by default — Docker only creates it automatically on macOS and Windows. On Docker 20.10 and newer you opt in with one line: extra_hosts: - "host.docker.internal:host-gateway". That maps the name to the Docker bridge gateway, so your container can reach services running on the host.

If you've moved a Docker project from a Mac to a Linux server, this is the error you hit:

Connection refused: host.docker.internal:3000

On macOS and Windows, host.docker.internal is a magic DNS name that resolves to your host machine's IP address. It's incredibly useful for connecting containers to local databases or APIs running outside of Docker.

But on Linux? It doesn't exist by default.

Why?

On macOS and Windows, Docker runs inside a lightweight virtual machine. host.docker.internal is a helper to bridge the gap between that VM and your actual host OS.

On Linux, Docker runs natively. There is no VM. The "host" is just... the host. But because containers are isolated, they still don't know the host's IP address automatically.

The Fix

You don't need hacky scripts or hardcoded IPs. Docker 20.10+ supports a special host-gateway value.

In Docker Compose

Add extra_hosts to your service definition:

services:
my-app:
image: my-app:latest
extra_hosts:
- "host.docker.internal:host-gateway"

That's it. Now host.docker.internal will resolve to the host's Docker gateway IP (usually 172.17.0.1), allowing your container to talk to services listening on the host.

Important: make sure the service on the host is listening on 0.0.0.0 (or on the Docker bridge IP), not just 127.0.0.1. Otherwise the container can reach the host, but the host refuses the connection.

In Docker CLI

docker run --add-host host.docker.internal:host-gateway my-image

A Note on Firewalls

If it still doesn't work, check your firewall (UFW or iptables). UFW may block forwarded traffic from Docker networks.

To allow traffic from the default Docker subnet:

sudo ufw allow from 172.17.0.0/16

This permits container → host connections without exposing the docker0 interface itself.

Does host.docker.internal work on Linux in 2026?

Yes, but only if you opt in. Docker Engine 20.10 added the host-gateway magic value back in late 2020. Every modern Docker version since (20.10, 23.0, 24.0, 25.0, 26.0, 27.0) supports it on Linux. You still have to add extra_hosts: ["host.docker.internal:host-gateway"] to each service. There is no auto-mapping like on Mac or Windows, and there will not be one — Linux runs Docker natively, so the helper is opt-in by design.

"Connection refused" vs "Name or service not known"

These two errors look the same to users but have different fixes:

  • Name or service not known / could not resolve host — DNS failure. The container does not know what host.docker.internal means. Fix: add the extra_hosts line above. This is the most common case.
  • Connection refused — DNS works, but the host service rejects the connection. Fix: bind your host service to 0.0.0.0 (or the docker bridge IP 172.17.0.1), not 127.0.0.1. A Postgres or Node server bound to localhost will refuse traffic from a container even after host.docker.internal resolves correctly.

If dig host.docker.internal inside the container returns an IP, you are in case 2. If it returns nothing, you are in case 1.

host.docker.internal not resolving in Docker Compose: full example

A complete docker-compose.yml you can copy:

services:
api:
image: node:20
command: node server.js
ports:
- "3000:3000"
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
DATABASE_URL: "postgres://user:pass@host.docker.internal:5432/mydb"

The container can now reach a Postgres running on the host at port 5432. Make sure Postgres is listening on 0.0.0.0:5432, not just 127.0.0.1.

FAQ

Frequently asked questions

Does host.docker.internal work on Linux?

Yes, but only if you add it yourself. Docker does not create the hostname automatically on Linux the way it does on macOS and Windows. Add 'host.docker.internal:host-gateway' under extra_hosts in Compose, or pass '--add-host host.docker.internal:host-gateway' to docker run.

Which Docker version added host-gateway support?

Docker 20.10, released in December 2020. Every release since supports it, including Docker 27 and 28. On anything older than 20.10 you have to hardcode the bridge gateway IP instead.

Why is host.docker.internal not found by default on Linux?

On macOS and Windows, Docker runs inside a virtual machine and needs a helper name to bridge the VM to the host. On Linux, Docker runs natively with no VM to bridge, so Docker never creates the name. You opt in with extra_hosts.

What IP does host.docker.internal resolve to?

The gateway of the container's Docker network — usually 172.17.0.1 on the default bridge. Custom Compose networks get their own gateway IP, which is why host-gateway is safer than hardcoding an address.

Why do I get 'connection refused' instead of a DNS error?

Connection refused means the name resolved correctly and nothing is listening on that port on the host. Usually the host service is bound to 127.0.0.1 only — bind it to 0.0.0.0 instead. 'Name or service not known' is the different problem: the extra_hosts entry is missing.

Does host.docker.internal work in Kubernetes?

No. Kubernetes does not support the host-gateway value. Use the node's IP address, a headless Service pointing at it, or a pod with hostNetwork: true.

Can I use host.docker.internal with docker run?

Yes: 'docker run --add-host host.docker.internal:host-gateway my-image'. It is the same mechanism the Compose extra_hosts entry uses.


Tired of Networking Issues?

Networking is the hardest part of self-hosting.

Deploy on Hostim.dev

At Hostim.dev, we handle the networking layer for you. Deploy your containers and let them talk to each other securely, without messing with extra_hosts or firewalls.