I just want to be able to browse my local docker containers on my PC by their container names, as if they're in DNS. Why is this so difficult?

So: I’ve spun up some containers named “kitten-service” and “puppy-service” on my workstation, for local development; and these containers can exchange vitally important kitten and puppy data between them internally by simply visiting their respective REST services on http:kitten-service and http:puppy-service; as long as they are doing so within the internal docker environment. Docker’s magical internal name service resolution just works! It even works with docker network aliases! Great!

But from my workstation which is hosting this vitally important data network, things are not so simple. I would like to simply visit http:puppy-service in my web browser and access the information I need, rather than having to visit http:192.168.69.16. But my options are quite limited. I’ve tried the following:

  1. Manually edit /etc/hosts on my workstation to provide the hostname/IP address mappings manually. This is far from ideal: what about when a new docker service such as http:ferret-service comes online? I can’t be expected to edit /etc/hosts manually every time a new cute animal service comes online. What about when I docker-compose restart and all the containers have brand new totally random IP addresses?

2.a) Install the libnss-docker package and add it to my /etc/nsswitch.conf. Nope, this just doesn’t work. It appears to be abandonware. Man page last updated in October 20th 2015.

2.b) libnss-mymachines. Also doesn’t seem to work. Apparently linux doesn’t consider docker to be relevant enough to include its containers in this VM hostname resolution subsystem.

2.c) libnss-libvirt. Also nope. See 2.b.

3.a). Spin up a docker container with a DNS proxy service like 4km3/dnsmasq, which simply forwards DNS requests to the super-secret internal dockerdns service; exposing an IP:port that’s available to the host machine.

This actually works! I can, for example, dig @192.168.69.4 puppy-service and get the puppy-service container’s IP. Perfect. Right?

But, no. I can’t simply add this resolver IP to /etc/resolv.conf because Ubuntu, in its infinite wisdom, has decided to grossly overcomplicate DNS resolution with its systemd-resolved Rube-Goldberg machine for hostname resolution. It overwrites /etc/resolv.conf when it sees fit; including when I shut down or restart dockerd. When I start dockerd or docker-compose up again; it does not do the needful by re-adding my special dnsmasq container’s IP as a resolver.

3.b) I’ve tried playing by Ubuntu / systemd’s rules and modifying /etc/systemd/resolved.conf with the following parameters:

DNS=192.168.69.4      # My dnsmasq container dockerdns proxy (which may or may not be up)
FallbackDNS=8.8.8.8  # Everything else

This works somewhat while dockerd is actually running and returning DNS query responses. But when I query anything that’s not within docker’s DNS remit, the request waits 10+ seconds before it times out and systemd tries the fallback DNS service of 8.8.8.8.

The result is that any time I browse a website that’s not hosted within dnsmasq such as google.com, I have enough time to go and make a cup of tea before the site starts loading in my browser. I’ve had enough tea by now that I’ve had to take 3 or 4 bio-breaks just typing this forum post.

Please help. Literally all I want to do is visit my locally-hosted docker services by the container’s name or its alias. This is such an obvious use-case it’s mind-boggling that it’s not built into docker by default.

Soon I’ll be trying the same thing on OSX. But I’ll save that trail of tears for another forum post.

Sincere thanks in advance for any advice; and I’m quite happy to be roasted for not realising all the obvious mistakes I’ve made on this journey.

Cheers,
A docker noob

Have you considered running a dns resolver in your network that allows to override (and inject) dns entries?
For instance pihole and unbound allow to add domains, including wildcard domains.

If you point a wildcard domain entry to your docker host, for instance *.vitally or *.docker.vitally (it doesn’t even matter if such a domain exists) and use traefik as a reverse proxy on port 80, combined with proxy host rules as labels on the containers that make the container respond to puppy.vitally you will have a nice solution with almost no maintenance. Of course your host would need to use the dns resolver in order to use the dns overrides.

1 Like

Have a look at my “ldddns” tool: https://ldddns.arnested.dk

It’s a daemon running in there background listening to docker events and broadcasting domain names for the containers using multicast DNS.

No fiddling with /etc/hosts, resolvers, running DNS-servers, etc. Just install the .deb package and enjoy :slight_smile: