Learning How Containers Communicate

In this lesson, we will see how communication happens between containers.

How can containers talk to each other?

If two containers are isolated, independent processes, how are they able to talk to one another?

While it is true that the code and processes running in a container are sandboxed, that does not mean the container has no way to communicate with the outside world. If containers could not communicate, we would not be able to connect them together to create a powerful, connected system of services that together make up our application.

Networks list

The docker-compose up creates a new network for the app. By default, all containers for our app are connected to the app’s network and can communicate with each other. This means that our containers, just like a physical or virtual server, can communicate outside themselves using TCP/IP networking.

We listed our currently defined networks using the following command:

$ docker network ls 

You should have seen some output similar to the following:

NETWORK ID NAME DRIVER SCOPE 
128925dfad81 bridge bridge local 
5bd7167263e8 host host local 
e2af02026928 usercode_default bridge local 
d1145155d62a none null local 

Networks explanation

The first network called bridge is a legacy network to provide backward compatibility with some older Docker features. We will not be using it now that we have switched to Compose. Similarly, the host and none networks are special networks that Docker sets up that we do not need to worry about.

The network we do care about is called usercode_default. This is our app’s dedicated network that Compose created for us. The reason Compose creates this network for us is simple: it knows that the services we are defining are all related to the same application, so inevitably they are going to need to talk to one another.

How do containers on usercode_default find each other?

All Docker networks (except for the legacy bridge network) have built-in Domain Name System (DNS) name resolution. That means that we can communicate with other containers running on the same network by name. Compose uses the service name (as defined in our docker-compose.yml) as the DNS entry. So if we wanted to reach our web service, it would be accessible via the hostname web. This provides a basic form of service discovery: a consistent way of finding container-based services, even across container restarts.

This explains how we were able to connect from the Adhoc container running the redis-cli to our Redis server running as the redis service. Here is the command we used:

$ docker-compose run --rm redis redis-cli -h redis

The option -h redis says, “Connect to the host named redis.” This only worked because Compose had already created our app’s network and set up DNS entries for each service. In particular, our redis service can be referred to by the hostname redis.

Get hands-on with 1200+ tech skills courses.