Docker 1.10 access a container by its hostname from a host machine
As answered here there is a software solution for this, copying the answer:
There is an open source application that solves this issue, it's called DNS Proxy Server
It's a DNS server that resolves container hostnames, and when it can't resolve a hostname then it can resolve it using public nameservers.
Start the DNS Server
$ docker run --hostname dns.mageddo --name dns-proxy-server -p 5380:5380 \-v /var/run/docker.sock:/var/run/docker.sock \-v /etc/resolv.conf:/etc/resolv.conf \defreitas/dns-proxy-server
It will set as your default DNS automatically (and revert back to the original when it stops).
Start your container for the test
docker-compose up
docker-compose.yml
version: '2'services: redis: container_name: redis image: redis:2.8 hostname: redis.dev.intranet network_mode: bridge # that way he can solve others containers names even inside, solve elasticsearch, for example elasticsearch: container_name: elasticsearch image: elasticsearch:2.2 hostname: elasticsearch.dev.intranet
Now resolve your containers' hostnames
from host
$ nslookup redis.dev.intranetServer: 172.17.0.2Address: 172.17.0.2#53Non-authoritative answer:Name: redis.dev.intranetAddress: 172.21.0.3
from another container
$ docker exec -it redis ping elasticsearch.dev.intranetPING elasticsearch.dev.intranet (172.21.0.2): 56 data bytes
As well it resolves Internet hostnames
$ nslookup google.comServer: 172.17.0.2Address: 172.17.0.2#53Non-authoritative answer:Name: google.comAddress: 216.58.202.78
Here's what I do.
I wrote a Python script called dnsthing, which listens to the Docker events API for containers starting or stopping. It maintains a hosts
-style file with the names and addresses of containers. Containers are named <container_name>.<network>.docker
, so for example if I run this:
docker run --rm --name mysql -e MYSQL_ROOT_PASSWORD=secret mysql
I get this:
172.17.0.2 mysql.bridge.docker
I then run a dnsmasq
process pointing at this hosts
file. Specifically, I run a dnsmasq instance using the following configuration:
listen-address=172.31.255.253bind-interfacesaddn-hosts=/run/dnsmasq/docker.hostslocal=/docker/no-hostsno-resolv
And I run the dnsthing
script like this:
dnsthing -c "systemctl restart dnsmasq_docker" \ -H /run/dnsmasq/docker.hosts --verbose
So:
dnsthing
updates/run/dnsmasq/docker.hosts
as containersstop/start- After an update,
dnsthing
runssystemctl restart dnsmasq_docker
dnsmasq_docker
runsdnsmasq
using the above configuration, boundto a local bridge interface with the address172.31.255.253
.The "main" dnsmasq process on my system, maintained byNetworkManager, uses this configuration from
/etc/NetworkManager/dnsmasq.d/dockerdns
:server=/docker/172.31.255.253
That tells dnsmasq to pass all requests for hosts in the
.docker
domain to thedocker_dnsmasq
service.
This obviously requires a bit of setup to put everything together, butafter that it seems to Just Work:
$ ping -c1 mysql.bridge.dockerPING mysql.bridge.docker (172.17.0.2) 56(84) bytes of data.64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.087 ms--- mysql.bridge.docker ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 0.087/0.087/0.087/0.000 ms
To specifically solve this problem I created a simple "etc/hosts" domain injection tool that resolves names of local Docker containers on the host. Just run:
docker run -d \ -v /var/run/docker.sock:/tmp/docker.sock \ -v /etc/hosts:/tmp/hosts \ --name docker-hoster \ dvdarias/docker-hoster
You will be able to access a container using the container name
, hostname
, container id
and vía the network aliases
they have declared for each network.
Containers are automatically registered when they start and removed when they are paused, dead or stopped.