Hi there! In our previous post you have seen how to containerize a web application by dividing it into three different containers. An application like this that consists of many containers can be launched by just one single command with Docker Compose which will be introduced in this post.

##Docker Compose

If your application consists of several Dockerfiles and therefore several containers you can build them individually with the Docker commands. This can get annoying if you have dozens of containers. The solution is Docker Compose. Compose allows you to define a single file for a multi-container application, so in the end only a single command is needed to get everything running. We will show you how this will work in general, but be aware that Compose is not recommended for using it in production yet.

Compose comes with all the necessary CLI commands for managing your application’s life cycle, like e.g. start, stop and rebuild services or view the status of running services. To see the environment variables check out this link but keep in mind that it is not recommended to use them for connecting to linked services. You should rather use the link name.

##Installation

First you need to install Compose. On Windows install Compose with curl and run the commands:

 curl -L https://github.com/docker/compose/releases/download/1.2.0/docker-compose-`u name -s`-`uname -m` > /usr/local/bin/docker-compose
 chmod +x /usr/local/bin/docker-compose

or as Python package:

$ sudo pip install -U docker-compose

Verify your installation with docker-compose --version.

##Three steps

Basically there are just three steps to use Compose and run your entire app with only one command.

  1. Define the Dockerfile for your app that defines its whole environment.
  2. Define the services that make up your app, so they can be run in an isolated environment. This will be done in docker-compose.yml.
  3. Run docker-compose up.

##docker-compose.yml

In this file you specify your app’s services. Each service must specify exactly one of image or build, whereas image can be the a remote or local tag or the partial ID and build specifies a path or directory containing a Dockerfile. If the path is a relative path it will be relative to the docker-compose.yml itself.

You do not need to specify options such as CMD or VOLUMES in docker-compose.ymlbecause docker run` respects these options from the Dockerfile. Further options are e.g. to link containers, expose ports or mount paths as volumes. For further reference check out the official Docker website.

##Sample project

Assuming you have a Python project as in our first sample app, you have defined the Dockerfile and the requirements.txt. Your project is not only a simple webserver but contains also a database (postgres). To specify these services, link everything together and describe which Docker images your docker-compose-yml should look something similar like this:

db:
  image: postgres
web:
  build: .
  command: python manage.py runserver 0.0.0.0:8000
  volumes:
    - .:/code
  ports:
    - "8000:8000"
  links:
    - db

To build the project use docker-compose run. The command

$ docker-compose run web django-admin.py startproject myproject .

will build an image for the web service with the given Dockerfile. The second part will run inside a container built using this image. The next step is to set up the correct database connection. Therefore you need to change the DATABASES=... definition in myproject/settings.py, which are defined by the postgres Docker image.

Finally you run the command docker-compose up which will link everything together and that’s it!