Docker containers can access local services running on the host by connecting to host.docker.internal
.
Note:
- it only works on Docker for Windows / Mac by default
- on Linux it’s useless for now but could be available starting from 20.03
- it’s Docker specific so it doesn’t exist in CRI-O or ContainerD with Kubernetes
The Docker docs say:
The host has a changing IP address (or none if you have no network access). We recommend that you connect to the special DNS name
host.docker.internal
which resolves to the internal IP address used by the host. This is for development purpose and will not work in a production environment outside of Docker Desktop for Windows / Mac.Source: https://docs.docker.com/docker-for-windows/networking/#use-cases-and-workarounds
Use Case
What does this allow you to do exactly?
You could spin up a database or perhaps a development version of something like Consul and want to access it from inside the container when using Docker for Mac/Windows. Using host.docker.internal will resolve the correct host IP every time, which will be handy when moving between networks etc (as you can’t use localhost as the docker engine is running in a VM).
Implementation
In 20.03 (moby/moby#40007) added support for a magic string host-gateway
that can be passed to ExtraHosts (–add-host) to reliably pass the Docker host IP to your containers.
Adding --add-host=host.docker.internal:host-gateway
to docker run
adds the
host.docker.internal DNS entry in /etc/hosts and maps it to host-gateway-ip.
docker run -it --add-host=host.docker.internal:host-gateway alpine cat /etc/hosts
Or for docker-compose:
# docker-compose.yml
my_app:
image: ...
extra_hosts:
- "host.docker.internal:host-gateway"
This is also available as daemon flag called host-gateway-ip which defaults to the default bridge IP.
To have an identical behaviour across all Docker versions (Windows, Linux, Mac):
- add
"dns-resolve-docker-host": false,
in the Docker daemon config - add
--add-host host.docker.internal=host-gateway
to your container