Did you know that you can use the service name of a container or id to connect to it on Docker?

If you have used the --link option when launching a container or docker compose, you can call the container by its name or id from other containers. But how does this work?

The answer is simple: DNS.

Whenever you launch a container, Docker provides a network for you and uses the DNS service provided by the Docker daemon.

You can override the default docker network and DNS settings Check the docs here

Scenario

Let’s assume that you have 3 tier application: Frontend, Backend, and a Database.

Your backend needs to be able to connect to the database. The safest way to do so is to keep your database in a private network to connect to it.

With docker you can use the service name or container ID as the server name in your configuration file.

Ex.:

cn = mysql.connect(user='produser',
                 password='secretvalue',
                 host='svc_database', # this is the service name in the incoming example
                 database='mysuperapp')

Launching a few containers

Clone the following repository using the command below:

git clone git@github.com:gdi3d/docker-dns.git .

Now take a look at the file docker-compose.yml in the repository you just cloned.

version: "3.9"  # optional since v1.27.0
services:
  svc_frontend:
    image: busybox:latest
    command: top
  svc_database:
    image: busybox:latest
    command: top
  svc_backend:
    image: busybox:latest
    command: top

You can see three services defined:

  1. svc_frontend: App frontend
  2. svc_database: App database
  3. svc_backend: App backend

To make things easier we’re using busybox image to simulate the services.

Launch the containers using docker-compose up -d.

You can check that the containers are running using docker ps

The Test

We’re going to test the following:

  1. Where’s the Docker DNS service running at (the ip address)
  2. Try to ping a container by its service name and ID.
  3. Are the requests being resolved by Docker DNS service?.

These are our containers with their service name and IDs:

Service Name ID
svc_frontend 1ee9c76938ee
svc_database fe0228bd99a5
svc_backend a96e0cb74351

Where’s the Docker DNS service at?

Let’s access svc_backend container and type cat /etc/resolv.conf

Here you can see that nameserver has been pointed to 127.0.0.11. That’s the Docker DNS service provided by the Docker daemon.

Pro tip: You don’t need to type the whole ID of the container to perform an operation, just use the first two or three characters

Try to ping a container by it’s service name and ID

You can check the connectivity against the svc_database using the ping command:

As you can see, we obtain the same response when calling it by its service name svc_database or docker id fe0228bd99a5.

They both resolve to the same IP 172.19.0.3 as expected.

Are the requests being resolved by Docker DNS service?

Let’s use nslookup to have a detailed report on what’s going on when we try to call a container by its service name or ID.

Running these two commands will give us a better understanding of what’s going on: nslookup svc_database and nslookup fe0228bd99a5

Server:		127.0.0.11
Address:	127.0.0.11:53

Non-authoritative answer:
Name:	svc_database
Address: 172.23.0.2

--------------------------

Server:		127.0.0.11
Address:	127.0.0.11:53

Non-authoritative answer:
Name:	fe0228bd99a5
Address: 172.19.0.3

From the results of nslookups we can see that the request is made using the docker DNS service at 127.0.0.11 and that, again, using the service name svc_database or the container id fe0228bd99a5 the destination is the same ip 172.19.0.3

Further Reading

If you want to know more about how the docker networking works you can check the official documentation