Communication between Docker containers

Having an app running from within Docker container is fun, that’s for sure. But do you know what would be even more fun? Many apps running from within containers and talking to each other. Imagine that after playing enough with microservices, you finally decided to split some real monolithic web application into:

  1. container, serving static web content, and
  2. container, serving data through some sort of RESTful API.

First container opens 80th port and, while serving html/css/js by himself, talks to the second container when data request comes.

So idea is simple, but there’s one thing. How exactly those containers will communicate? How do they even find each other?

Docker networks.

Images and containers are not the only things that Docker creates. It also has its own networks and comes with three of those, named:

  1. bridge
  2. host
  3. none

‘bridge’ is default network for all containers, but you can specify target network while starting container. It’s also OK to connect container to several networks with docker network attach . Cool thing is that unless you messed with Docker configuration, all containers within the same Docker network can see and talk to each other. You have to do an extra effort to allow inbound connections initiated from host network (e.g. -p80:80 ), but internal connections – no questions asked.

The following example demonstrates that: nginx container acts as a private web server, and busybox talks to it.

Now, talking from container to another container by its IP address is not a problem. Finding IP address – is. You see, the fact that today my nginx container listens at doesn’t mean that tomorrow it will stay this way. Order in which containers start, moving container to another network, network settings itself – anything can change the IP. If we’re building distributed application, we need something more predictable.

How to survive dynamic IP.

There’re actually at least three ways:

  1. use --link
  2. use container name and user-defined network
  3. use network alias


As of today, --link  is marked as legacy feature. But it still works, nobody watches, so why not.

Every container has a name – either explicitly specified, or auto generated. I started nginx without --name  parameter, so Docker intervened and called my container nauseous_aryabhata. Now, if I start the second container with --link=nauseous_aryabhata  argument, it will receive a whole bunch of environmental variables, as well as additional entry in /etc/hosts  file:

Because of that extra entry I can use nauseous_aryabhata host name in my web requests, or read IP address from environment variables.

Assign name to container and put it into user-defined network.

What I don’t like about cool features is the word ‘legacy’ in front of them, so --link  might be aesthetically pleasing, but it’s not suitable for production environment. There’s another way – don’t use default ‘bridge’ network and create your own, bridge-like user-defined network. For those networks Docker silently adds lightweight DNS server, which keeps Name+IP entries for all containers within the same network, so we can use container name again.

Step one. Create new network:

Step two. Start nginx container, call it ‘web’ and attach to newly created network:

Step three. Start another container in the same network and check if it can talk to ‘web’:


Use network alias.

This approach is very similar to previous one, but instead of container name we can assign and use network alias.

Now all requests to http://webserver  will be routed to nginx container. If both name and network alias are specified, both of them can be used.

Bottom line.

Communication between Docker containers using TCP/HTTP is not that hard. We covered the basics, but there’s even more interesting stuff in Docker networking: different types of networks, custom network bridges and even overlay networks, which can span across multiple hosts. But that’s another story.

2 thoughts on “Communication between Docker containers

Leave a Reply

Your email address will not be published. Required fields are marked *