Understanding Inter-Container Communication for Docker

In most of your current architectures, you probably separate your Web Server from your Database (virtual) server. This post will show how to build that type of architecture with Docker containers. Of course, having Docker containers communicate has more uses than a web server and a database, but the pattern you would use stays the same.

1. Starting a Postgresql Docker Image

When you run docker images you can see that we have already an image titled training/postgres. This image was created by Docker for their tutorials and is based off of Ubuntu with Postgresql 9.3. We thought this would be a good way to show you that you can run many different Linux containers on the same underlying kernel.

When we start the container we are going to take advantage of Docker’s ability to give our containers meaningful names. Start the postgresql image as a container and name it db like so:

$ docker run -d -P --name db training/postgres

By using the –name flag we can assign a name to our container rather than the default behavior where a random name is assigned to the container. We can now use db as the container name rather than remembering the random digit sequence or the random name. In general, when doing real work, we recommend you name your images so your architecture is easier to follow.

Let’s check which ports our image is exposing:

$ docker ps
CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS              PORTS                        NAMES
ba9b681f21b3        training/postgres:latest   su postgres -c '/usr   6 seconds ago       Up 4 seconds        0.0.0.0:49160->5432/tcp   db

You can see that Docker has mapped port 49160 to the port 5432 in the container, which is the default port for Postgresql. And now let’s link it to our new image we created.

2. Starting the spousty/myfedora Image to talk to the DB Container

First make sure your new image is not running in a container by doing a docker ps. If it is go ahead and kill the container and actually remove the container.

$ docker kill hopeful_kowalevski
hopeful_kowalevski
$ docker rm -f hopeful_kowalevski
hopeful_kowalevski

Now we are going to start up that image again but this time we are going to link it to our Postgresql container. We are also going to name the container this time to make it easier to remember than hopeful_kowalevski. Finally, we will also just start at the command prompt so we can use the Postgresql command-line client. Actually hooking up the web piece to the database is beyond the scope of this class.

$ sudo docker run -i -t --name web --link db:postdb spousty/myfedora /bin/bash

The link part of this command is of the form:

--link name:alias

Where name is the name of the container you want to link to and alias is for the link inside the container you are about to spin up. Once you are at the command prompt let’s go ahead and take a look at what the -–link option did inside this container. First you will see that Docker added some environment variables to this container. To see the environment variables, execute the following command:

$ env | grep POSTDB
POSTDB_NAME=/web/postdb
POSTDB_PORT=tcp://172.17.0.31:5432
POSTDB_PORT_5432_TCP_ADDR=172.17.0.31
POSTDB_ENV_PG_VERSION=9.3
POSTDB_PORT_5432_TCP_PORT=5432
POSTDB_PORT_5432_TCP=tcp://172.17.0.31:5432
POSTDB_PORT_5432_TCP_PROTO=tcp

So you can see that our web container now has assigned mappings for this container to attach to the db container. If we look in /etc/hosts, we will see that Docker also gave an ip mapping for the container aliased postdb:

$ cat /etc/hosts | grep postdb
172.17.0.31 postdb

All the “wiring” is in place, it is time to see if this all really works.

3. Testing the Connection

Here comes the easy part! You will need one piece of background information; Docker made the username and password for Postgresql equal to docker:docker. And with that let’s try to execute some SQL commands in the postgresql container from the web container. Enter the following commands at the terminal in the web container:

$ psql -h postdb -p $POSTDB_PORT_5432_TCP_PORT -V
psql (PostgreSQL) 9.3.5

Now let’s just log in and see what databases there are in the database

$ psql -h postdb -p $POSTDB_PORT_5432_TCP_PORT -U docker
 psql (9.3.5, server 9.3.4)
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.

docker=# \db
List of tablespaces
Name        |  Owner   | Location
------------+----------+----------
pg_default  | postgres |
pg_global   | postgres |
(2 rows)

To exit out of PostgreSQL just type \q [Enter] And with that you know enough to proceed on to the other labs.