Docker Series — Moving past one container

nolan grace
Pintail.ai
Published in
7 min readJan 4, 2018

In my last article I talked about how to build your own Docker image from scratch using a Dockerfile. Let’s take that a step further. In my opinion, the real power of Docker doesn’t come from its ability to build and run lightweight containers, but instead from its ability to quickly and easily start and orchestrate a number of different containers. To do this we are going to use something called Docker Compose.

To help us get a sense of Docker Compose, let’s compare Docker to an orchestra. We are trying to perform a symphony of computation and we need everyone to be doing their part correctly and to be timed with everyone else in the orchestra. Docker containers are like different musicians playing their instruments and Dockerfiles are like sheet music telling each musician what to do. In this metaphor we still need a conductor to organize everyone. Docker Compose is that conductor who manages how many people are playing, keeps everyone on rhythm, and makes sure everyone is on the same page. Container orchestration is a common term used in the containerization space and Docker Compose is the simplest of all the container orchestrators. I will be talking about more complex and sophisticated container orchestration tools in my next article.

Let’s See it Work!

To get started understanding how Docker Compose works in practice, I have created simple example. In this simple example we are going to put a load balancer in front of the pintail-whoami Docker image; this way, we can easily see how Docker containers startup, communicate, and scale with Docker Compose.

As you can see from the diagram below, Docker Compose is going to spin up the containers for us within a named and isolated network. Containers running on this network can only be accessed by other containers running on the network or through ports mapped out from the containers to our host OS. Below you can see there is a red X next to the two pintail-whoami docker containers because we are not binding any ports from those containers. That doesn’t mean, however, that we won’t be able to access them. The Nginx container is bound to the host OS from port 80 on the container to port 80 on your host making it accessible from a browser running on your host OS. This Nginx container is also configured to forward any calls made to localhost directly to any of the pintail-whoami containers running within this projects Docker Compose isolated environment. For this Docker Compose project you can think of the Nginx container as the gatekeeper because none of the other containers have ports mapped out of the Docker Compose isolated network any traffic must me go through Nginx.

To run this example yourself first make sure you have Docker installed on your computer. Docker Compose installs automatically with Docker for Windows and Docker for Mac, but if you are working in a Linux environment you may need to install Docker Compose manually. More information about installing Docker Compose can be found here.

Now that you have Docker Compose up and running, pull down the most recent version of the pintail-whoami project. Open up a terminal or command line window and follow the instructions below.

If you have cloned the project before navigate to the directory and run

$ git pull origin master

Otherwise use your terminal window to navigate to a directory where you would like to pull down the project and run

$ git clone https://github.com/pintail-ai/pintail-whoami.git

To tell Docker Compose to start up the Docker containers run the command below.

$ docker-compose up -d

To see the Docker containers that were started by Docker Compose run

$ docker-compose ps

To see the logs of all the containers started by Docker Compose run

$ docker-compose logs -f

Once you can see that the images started up correctly go to localhost in your browser to see pintail-whoami running

To tell Docker Compose to scale up the number of pintail-whoami containers running execute the command below.

$ docker-compose up --scale pintail-whoami=2 -d

After you have scaled up the number of pintail-whoami containers running greater than one you can refresh localhost and you should see the ID beneath “Welcome to the Pintail.ai Docker Example!” change.

This number is the Docker container ID of the specific container that is running web application and seeing it change indicates that the nginx-proxy is forwarding you to different Docker containers!

To clean everything up simply run the command below.

$ docker-compose down

Docker Compose File

To understand how Docker Compose knew how to do everything let’s take a look at the docker-compose.yml file in the pintail-whoami project.

version: '2'
services:
nginx-proxy:
image: jwilder/nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
pintail-whoami:
image: pintailai/pintail-whoami:0.0.1
environment:
- VIRTUAL_HOST=localhost

A docker-compose.yml file does for Docker Compose what a Dockerfile does for building Docker images. The Compose yml file contains all the instructions about which Docker containers should be started, specific details about how the container should be started, and the relationships between the containers started by Docker Compose.

The most important part of the docker-compose.yml file format is the definition of the services which you can see under the “services:” line. Everything under this is where we design all of the docker containers we would like started. Here we are telling Docker Compose to start up two different containers named nginx-proxy and pintail-whoami. Below both services you can also see the image, ports, volumes, and environment variables to be used with each container. These are all attributes that you may have run across working with individual Docker images. The great part about Docker Compose is that you can specify everything you want in one place rather than having to run a bunch of different Docker commands to try to start everything and organize all your containers correctly.

For more information about writing a Docker compose yml file take a look at the official documentation here.

In summary, Docker Compose is a extremely easy to use and a useful tool for running a multi-container Docker application. Docker Compose, however, is limited to single node environments which makes it more appropriate for development and CI environments. In my next article in this series I will talk about how we take things one step further into production.

Docker Compose Commands

Docker Compose Up

$ docker-compose up [options] [ — scale SERVICE=NUM…] [SERVICE…]

This command is the first one you will use with Docker compose. When you run this command in a directory that contains a docker-compose.yml file Docker compose will find the file and use it to start up the containers.

Options:

--scale
This setting is used to change the number of containers you would like to have run for a specific service. Simply include the service and the number in the format below and you will be off to the racesdocker-compose up — scale pintail-whoami=2 -d-dThis setting will save you a lot of command line windows and tabs. This setting will tell Docker compose to run in a background daemon rather than locking up your current window.-fThis setting can be used to specify a different Docker compose yml file. Simply use the format below to specify any yml file you would like to use regardless of the name. Without this setting Docker compose will always look for a file named ‘docker-compose.yml’ by default.$ docker-compose -f docker-compose-test.yml up -d

https://docs.docker.com/compose/reference/up/

Docker Compose Ps

$ docker-compose ps [options] [SERVICE…]

Use this command to view all the containers for a specific Docker compose application. This command is similar to the “docker ps” command except it will only show you the images for the current docker-compose.yml file with which you are working.

https://docs.docker.com/compose/reference/ps/

Docker Compose Logs

$ docker-compose logs [options] [SERVICE…]

This command is used to view the logs for all the Docker containers running for a specific Docker compose application. Use the -f flag to follow the logs as shown below.

$ docker-compose logs -f

https://docs.docker.com/compose/reference/logs/

Docker Compose Stop

$ docker-compose stop [options] [SERVICE…]

This command is used to stop one or more services being run by Docker Compose. This command is similar to the ‘docker stop’ command which will only stop the docker image in its current state. Use this command to stop your Docker Compose application without losing anything. With this command you can always start everything again by simply running ‘docker-compose up -d’ again and all the containers will start again in the same state you left them.

https://docs.docker.com/compose/reference/stop/

Docker Compose Down

$ docker-compose down [options]

Be very careful with this command. Docker compose down is very destructive and will stop and remove all the container in your Docker compose application without any hope of recovery. Only use this command when you are ready to completely remove all the containers you have been working with including all data within them that isn’t mounted to an external volume.

https://docs.docker.com/compose/reference/down/

--

--

nolan grace
Pintail.ai

I like working with data a little more than I should. Solution Architect at BP3