So far in our Docker series we’ve covered What is Docker, Docker Basics which just prised the doors open of what Docker can do, Linking and Volumes as well as the Dockerfile to create custom Docker images. And yet, we’re still just scratching the surface of what Docker can do and how it can transform your environment.
In this article, we’re going to go through Docker Compose, which is the start of the multi-container orchestration tools. In our example for Linking and Volumes, we went through a basic WordPress site which had a total of 4 containers. These were MySQL, WordPress with Apache and then a data container for each.
While this wasn’t too difficult to setup, if we keep expanding it out further then it’ll become a page of commands again to rebuild the environment. With Docker Compose, we’re going to reduce that all to a single command again with a nice simple config file. While it sounds too good to be true, this is why Docker is such a powerful toolset and creating all the hype.
Installing Docker Compose
So far, Docker Compose still isn’t a standard inclusion with a Docker installation. Like the main binary however, Docker Compose is Go based so all you need to do is download and install a single binary.
To install on a Linux based system, all you need to do is run the following:
curl -L https://github.com/docker/compose/releases/download/1.4.2/docker-compose-`uname -s`-`uname -m` > /usr/bin/docker-compose chmod +x /usr/bin/docker-compose
This will download the corresponding binary for your system to your system and set it as an executable. It can now be directly called via the docker-composecommand.
Step 1: Map out your existing system
While it’s tempting to dive head first into docker-compose, I find it far more successful to map out your platform first. If you have your scenario working in Docker already, that’s a great start. This means that you have already ironed out any potential bugs and gotchas before converting it into Docker Compose format. Things like the network ports, any socket connections and similar all need to be considered.
For this tutorial, we’re going to continue on with the existing examples in the previous Linking and Volumes tutorial, which was a WordPress based scenario. Here’s what it looked like:
Without Docker-Compose, this took 4, long winded commands to run. While this may not seem too bad, the moment you change one part like the name of a container, you need to rebuild it all again to ensure the linkages are correct.
By writing a docker-compose file, we eliminate this hassle and can bring it back into an easy to read file with a single command to deploy.
Step 2: Start your Docker Compose Config
With a fully mapped system, we can now begin the configuration. Ensure you create a new directory for this, then within the directory create a “docker-compose.yml” file. This is in the YAML format, which is an easy to read format for both humans and computers.
NOTE: Whitespace in YAML files is very important. Make sure you intent everything with the same amount of spaces.
Each container is named within the configuration is defined in a block. If you think about the command line options you use to define your container, this config is essentially an easy to read representation of this.
Here’s what our WordPress docker-compose.yml looks like:
dbdata: image: mysql:5.6 volumes: - /var/lib/mysql dbserver: image: mysql:5.6 volumes_from: - dbdata environment: - MYSQL_ROOT_PASSWORD=Memzoh78 - MYSQL_DATABASE=wordpressdemo - MYSQL_USER=conetixdemo - MYSQL_PASSWORD=Xumkos26 wpdata: image: wordpress:latest volumes: - /var/www/html wpdemo: image: wordpress:latest links: - dbserver:mysql volumes_from: - wpdata ports: - "8080:80" environment: - WORDPRESS_DB_NAME=wordpressdemo - WORDPRESS_DB_USER=conetixdemo - WORDPRESS_DB_PASSWORD=Xumkos26
We had to remove the dash from our names for the containers from the previous article as Docker Compose only accepts a-z and A-Z characters only. This is because it takes care of the naming and versioning of the containers when it deploys, so for our instance we’ve simply removed them.
If you have a custom Dockerfile, you can specify build instead of image. the name of the value for the build then needs to be a directory name, which should contain your Dockerfile and any associated files. There’s no need to build the image first if you have this specified, Docker Compose will take care of this for you.
Don’t be afraid to scour the web for examples that others have used, if the platform you’re using is the same or similar. It’s always good to see what others are doing, even if you end up using something slightly different.
Step 3: Build and Deploy
Once you have your docker-compose.yml file complete, you can now run it. To start all the containers, simply call:
This will build any required containers, then deploy. You should then get an output like this:
As you’ll notice, Docker also colour codes the logging so that you can easily see what container they belong to. This is great for narrowing down the initial issues, as you can see exactly what’s going on within the one screen.
By default, this runs in the foreground and therefore will stop all the containers if you exit docker-compose. In a production environment, you can use:
docker-compose up -d
Like all other Docker -d flags, this runs it as a daemon and therefore the containers will continue to run.
Docker Compose is simple yet essential for multi-container deployment. It brings your deployment down to a single command again, which is great for simplicity. This is really becomes a valuable tool once you start working on real world scenarios, since most real world deployments involve multiple containers.
We’ve actually converted this website (which is Django based) over to Docker, using Docker Compose to test and deploy. This will be written up as a separate article, since it’s there’s a lot of lessons learnt which others can leverage.
If you have any questions, please feel free to ask in the comments below.