Skip to main content

Accessing dockerd host from Docker container

Background

When using Docker, you have the "dockerd host" (i.e. the platform managing the containers) and you have the running containers. Each container has a localhost and the "dockerd host" has its own localhost. Whether you use --network host or not, you can not use localhost to communicate between the "dockerd host" and the container.

If you are anything like me, you'll often find yourself setting up quick and dirty services running in a container that is hosted with --network host and available on localhost from the context of the "dockerd host". Let's say its a caching service. In addition to the caching service being available on the "dockerd" host, you'll then want to use that containerized caching service from another container ...only you can't because of the non-route-ability of localhost. For these quick and dirty one-offs, I don't want to have to think about domain names, user network configurations, or specific IP addresses. If localhost isn't an option (because of containerization), I now have to resort to the more complicated setups ... or do I?

host-gateway

When using Docker containers within docker networks, sometimes there are the host.docker.internal and/or gateway.docker.internal host names that you can use to point at services on the host. In my case, these host names are not available. Although they can explicitly be made available via the --add-host argument.

When dockerd starts, it sets a host-gateway IP that is the default bridge between a "regular" container and its host. You can explicitly set this value using the --host-gateway-ip argument in the dockerd startup scripts. host-gateway is a special string that can be used in the --add-host argument of a docker command that creates containers (e.g. run, create, build). This argument automatically appends various hosts to the container's /etc/hosts file so that you don't have to setup a DNS or any other fancy service that needs to be managed.

Knowing this, you can explicitly set the host.docker.internal to IP mapping with --add-host host.docker.internal:host-gateway.

dockerhost

Explicitly adding host.docker.internal mapping to a container is all well and good, but I don't like explicitly messing with mechanics that should be implicit and I certainly don't like using reserved namespaces (i.e. docker.internal). The issue of using host.docker.internal is compounded by the fact that if I want to use a Host lookup based web service, I'd have to hi-jack the docker.internal domain in the web service configuration to handing the request effectively. And that just feels weird.

As a solution to this problem, I've started using a new pattern: Using a play on the term localhost, I've started using a new term dockerhost.

dockerhost build Example:

docker build -t crazychenz/cache --add-host dockerhost:host-gateway $@ .

The above command enables me to host (in another container) a caching service that I can connect to from this new docker build process. Having this allows me to point a generic APT sources.list file at the caching service without having to worry about DNS, VPNs, or other complicated methods to manage the access to my "dockerd host".

Conclusion

The primary takeaway here is that from now on, whenever developing a Dockerfile that is intended to host a service for other containers, I intend to always add the --add-host dockerhost:host-gateway argument to the build and possibly the runtime command.

Resources

Comments