Search code examples
dockernetwork-programming

What is running on host.docker.internal host?


I'm just curious, what is running on host.docker.internal host?

This service routes packages from docker container to services on host network.

But what exactly is it?

I found out that it's not gateway.


Solution

  • I'll answer with a few things that I've found regarding the Linux implementation. I bet that the implementation details for Docker for Windows / Mac will be different.

    In short: host.docker.internal is a Name. Every service that runs on your host and binds to the network interface that is also set as the Docker Daemon host-gateway, it can be accessed from inside a container at host.docker.internal:[service_port].

    Example

    $ docker run -it --rm --add-host=host.docker.internal:host-gateway alpine
    / # cat /etc/hosts
    127.0.0.1   localhost
    ... (it has a few other lines here) ...
    172.17.0.1  host.docker.internal 👈👈👈
    

    How it works

    • --add-host (applies to the container): it adds the last the line you see above to the container's /etc/hosts and this way host.docker.internal resolves to the IP address of host-gateway

    • host-gateway (applies to the host): with a typical Docker installation, it's usually 172.17.0.1 (default bridge) but it can be changed/configured with dockerd, see the relative docs 👇:

    --host-gateway-ip ip      IP address that the special 'host-gateway'
                              string in --add-host resolves to.  
                              Defaults to the IP address of the default bridge
    

    More digging...

    You can check the Pull request that adds this feature: #40007

    The user describes that he did the following:

    What I did
    This PR allows containers to connect to Linux hosts by appending a special string "host-gateway" to --add-host e.g. --add-host=host.docker.internal:host-gateway which adds host.docker.internal DNS entry in /etc/hosts and maps it to host-gateway-ip.
    This PR also add a daemon flag call host-gateway-ip which defaults to the default bridge IP.
    Docker Desktop will need to set this field to the Host Proxy IP so DNS requests for host.docker.internal can be routed to VPNkit

    Historical context

    I think the history behind all this is more or less the following:

    • Linux users could access host services by using the IP address of the default bridge. The way Docker was setting up the networking offered that.
    • Windows / Mac users also needed to access the host but the networking there had more complexity because of the different OS. So Docker for Windows / Mac introduced this host.docker.internal thing.
    • It was also made available to Linux users as it's easier to use a Name than an IP address.

    further reading: