Resolve docker container IP from host OS using container name

Viewed 1783

I have a non-containerized nginx instance serving as reverse proxy for containerized as well as non-containerized services.

Since container IPs can change on reboot, I don't want to use them in the nginx config file. I was looking for a simple way to reference the containers. Docker containers can reference each other by container name i.e. DNS lookup of container names gives container's IP. I was looking for something similar but names should be resolvable from host OS.

Constraints:

Solution should work with existing containers. So no docker run ... commands

I have tried mageddo/dns-proxy-server. It is supposed to resolve container names but it does not even after setting the right environment variables.

sudo docker run -d \
--restart unless-stopped \
--name dns-proxy-server \
-p 5380:5380 \
-e MG_REGISTER_CONTAINER_NAMES=true \
--hostname dns.mageddo \
-v /opt/dns-proxy-server/conf:/app/conf \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc/resolv.conf:/etc/resolv.conf defreitas/dns-proxy-server

PS: Though nginx is taken as an example, the DNS lookup feature is helpful in many other scenarios. So I am looking for DNS lookup solution and not simply a fix for the nginx issue.

2 Answers

There is a solution which you can implement. Start the DNS server first.

docker run --rm --hostname dns.mageddo --name dns-proxy-server -p 5380:5380 \
  -v /opt/dns-proxy-server/conf:/app/conf \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /etc/resolv.conf:/etc/resolv.conf \
  defreitas/dns-proxy-server

Then run a test container to test the hostname

docker run --hostname test.intranet nginx

Testing it

ping test.intranet
PING test.intranet (172.18.0.3) 56(84) bytes of data.
64 bytes from 172.18.0.3 (172.18.0.3): icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from 172.18.0.3 (172.18.0.3): icmp_seq=2 ttl=64 time=0.050 ms
64 bytes from 172.18.0.3 (172.18.0.3): icmp_seq=3 ttl=64 time=0.052 ms
64 bytes from 172.18.0.3 (172.18.0.3): icmp_seq=4 ttl=64 time=0.046 ms

Processes outside of Docker can't access the Docker DNS system; except for one specific configuration they can't access the container-private IPs either.

Instead you can publish ports out of your containers using the docker run -p option or Compose ports: option. A port number you specify will be stable, and will survive across container restarts. If you don't want the port to be directly accessible off-host, you can limit it to only being accessible from the host's loopback interface.

docker run -d --name backend \
  -p 127.0.0.1:8001:3000 \      # port 8001 reaches this container, only on lo0
  ...
match /backend/ {
  proxy_pass http://localhost:8001/
}

If it's important for your nginx configuration to use the Docker-internal DNS, you can run the nginx proxy inside Docker too.

Related