Docker tutorial for user-defined networks

How to get docker containers to communicate without using –link

A quick docker tutorial for user-defined networks to help you transition from using –link to user-defined networks.

If you have been trying to get docker containers to communicate with each other and you are investigating using the –link option, you made have come across this warning message:

Warning: The –link flag is a legacy feature of Docker. It may eventually be removed. Unless you absolutely need to continue using it, we recommend that you use user-defined networks to facilitate communication between two containers instead of using –link. One feature that user-defined networks do not support that you can do with –link is sharing environmental variables between containers. However, you can use other mechanisms such as volumes to share environment variables between containers in a more controlled way.

Source: https://docs.docker.com/network/links/#communication-across-links

Here is a quick way to get docker containers to communicate using docker networks.

Why should containers communicate?

The long term plan is to microservice your monolithic projects. Make them smaller, more testable, more reusable and more maintainable.

Once you have your collection of microservices, you might want to test that they can use other microservices, or communicate amongst each other.

In my case, I often spin up new tools to play around with in isolation. And I need those tools to communicate with other tools. This is where the docker network comes in handy.

Networking Like a Docker Boss

A better way to get containers to communicate is to create a user generated network.

The user being you, and the network will be a default bridge network.

The command to create a docker network:

1
$ docker network create [yournetworknamehere]

So you add in the name you would like to give your network, eg “mynet”.

1
$ docker network create mynet

Check your network is create by typing in:

1
$ docker networks ls

You should see something like this:

NETWORK ID NAME DRIVER SCOPE
851fb69ba4ca bridge bridge local
fc3d1eddc10f host host local
f7151c7835b8 mynet bridge local
9ba12ad3dcea none null local

You will see your new network “mynet” has been added and by default it is a bridge network.

That’s all we need to get containers communicating to each other.

Inspect the docker network

Check what is currently on the network by running

1
$ docker network inspect mynet

And have a look at the sections that says:

1
2
3
"Containers": {

}

If you just created your network, you should see an empty section called “Containers” near the bottom of the inspect response. This indicates that currently there are no containers on this network.

Add containers to your custom user network

Check which containers you need to communicate with each other by doing the docker ps command:

1
$ docker ps

Get the ids or names of the containers from that list.

In my case I needed a container running jenkins to be able to communicate with a container running artifactory:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAME
16ec3d7051dd docker.bintray.io/jfrog/artifactory-oss:latest “/entrypoint-artifact” 42 hours ago Up 19 hours 0.0.0.0:8081->8081/tcp artifactory
2387b9d5e4df jenkins/jenkins:lts “/sbin/tini — /usr/l” 4 days ago Up 4 days 0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp tender_perlman

So I took the ids of the two containers: 16ec3d7051dd and 2387b9d5e4df.

Then you need to add those containers to your newly created custom user network:

1
$ docker network connect mynet 16ec3d7051dd
1
$ docker network connect mynet 2387b9d5e4df

The syntax is:

$ docker network connect [yournetworkname] [yourcontainerid]

Inspect the docker network again

If you run your inspect command again:

1
$ docker network inspect mynet

You should now see your newly connected containers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...
"Containers": {
"16ec3d7051ddbe58f6984d83e4d099390efa22fafd44d70bd843fb99d75dcd0f": {
"Name": "artifactory",
"EndpointID": "3630e109771441c422fc99a616f0888463a02ea3afc21ab5b60719cdd2b08729",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"2387b9d5e4dfb1073c8db90052fb9a4692fa227c55441163b08de64eddc27955": {
"Name": "tender_perlman",
"EndpointID": "fe4d002c5497339cc9117a7a3d997a1e57fedb171a93b25d4fa34c34788cfa3a",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
}
},
...

Now you have achieved your goal to get your docker containers to communicate.

Use curl to check your containers can communicate

In the response from the inspect command you should see your containers each have an “IPv4Address”.

Copy just the IP.

You can now use the docker exec command to test you can ping the other container:

1
$ docker exec -it  16ec3d7051dd ping 172.17.0.3

And you should see:

PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.122 ms
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.122 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.107 ms

Yay!

If you don’t see that, just check your details, use the correct container id/name. Use the correct ip (which you get by copying the IPv4Address from the “docker network inspect mynet” command you ran).

That was a quick overview on one of the ways to get docker containers to communicate.