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:
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.