Docker Compose is a tool for defining and running multi-container applications. A typical example, and one which we will use later, would be a web server container and a database container configured to work together to provide a web application. Docker Compose then allows you to start the whole application with a single command!
You start by creating a Dockerfile, to build docker images of your application – or you can use existing images from a registry. You then define your docker services that you need to run your app in a docker-compose.yml file (see example later). Finally, you can run the whole thing using the docker-compose up command!
That was a quick introduction. In this article I will break down how we go about creating the docker-compose.yml file and how to start the services defined within it.
To start, let’s have a look at how we can install Docker Compose on a linux docker host.
How to Install Docker Compose
First of all we need to grab the software. We can do this on Linux using Curl. On my system I did this by running:
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
This downloaded the docker-compose tool to /usr/local/bin. Once downloaded, you must make the file executable. This can be done with:
sudo chmod +x /usr/local/bin/docker-compose
Finally, we can test that everything is working as it should by running:
$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01
Looks good! Now we can move on to some examples of how docker compose can be used.
Docker Compose Commands
Docker-compose has a bunch of commands. We had a look at the version command earlier, which simply prints the version of docker-compose. We can see all the commands available by running docker-compose –help:
build Build or rebuild services bundle Generate a Docker bundle from the Compose file config Validate and view the Compose file create Create services down Stop and remove containers, networks, images, and volumes events Receive real time events from containers exec Execute a command in a running container help Get help on a command images List images kill Kill containers logs View output from containers pause Pause services port Print the public port for a port binding ps List containers pull Pull service images push Push service images restart Restart services rm Remove stopped containers run Run a one-off command scale Set number of containers for a service start Start services stop Stop services top Display the running processes unpause Unpause services up Create and start containers version Show the Docker-Compose version information
You can read about these commands in detail here. We will look at some of these commands as we work through some docker-compose examples.
Creating Services with Docker-Compose
The example I am going to use is to build a docker compose file that defines the containers needed to run a WordPress website. Rather than build a custom image using a dockerfile, I will be using two docker images from the docker hub – the mysql image and the wordpress image.
First of all, a directory needs to be created where we can store the docker-compose.yml file for the project.
$ mkdir composetest $ cd composetest
For this example I will use the following docker-compose.yml file:
version: '3.3' services: db: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest volumes: - web_data:/var/www/html ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_DB_NAME: wordpress volumes: db_data: {} web_data: {}
This file defines the docker containers we want to create, in this case we are using the mysql:5.7 and the wordpress:latest images. We are also specifying two docker volumes, which will be created to store the mysql databases and the wordpress content.
You can read about how to create a docker-compose.yml file here.
Starting Services
Note: Whenever we are running docker-compose commands for a project, we need to be working in the directory that contains that project’s docker-compose.yml file.
We use the docker compose up command to create the containers specified in the docker-compose.yml file:
$ docker-compose up -d
In this example I have also used the -d flag which is detached mode, meaning that the containers will run in the background. Running docker ps now will show the newly created running containers:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d0c119d3af19 wordpress:latest "docker-entrypoint.s…" 31 hours ago Up 25 minutes 0.0.0.0:8000->80/tcp composetest_wordpress_1 dcd325fd82ac mysql:5.7 "docker-entrypoint.s…" 31 hours ago Up 25 minutes 3306/tcp, 33060/tcp composetest_db_1
We can also use the docker-compose ps command:
$ docker-compose ps
Docker volume list shows that the two volumes have been created:
$ docker volume list DRIVER VOLUME NAME local composetest_db_data local composetest_web_data
For the wordpress container, port 80 was exposed (port 8000 on the docker host):
ports: - "8000:80"
Going to the public IP address – http://ipaddress:8000 – on the docker host results in us being able to see the wordpress install wizard:
Success! We now have WordPress being served from the wordpress container, whilst it’s database will be provided by the mysql container.
Note that in the docker-compose.yml file we specify that the containers created should always restart:
restart: always
This means that the containers will always restart if the docker host is rebooted.
The Docker-Compose Run Command
Docker-compose has a run command, which can be used to run one off commands against a service. For example we could use:
$ docker-compose run wordpress uptime
This would return the uptime of the container. A common use of the run command is to return the environment variables used by the service:
$ docker-compose run wordpress env
Note that we made good use of ENV variables in the docker-compose.yml file, to enable the wordpress service to authenticate with the mysql database server.
Stopping a Docker-Compose Service
You can stop your docker compose services by running:
$ docker-compose stop
This will stop all running containers that were defined and brought up by the docker-compose.yml file. If we want to remove the containers entirely we can use:
$ docker-compose down
Finally, if we want to remove the containers AND remove the volumes containing the data for the website and the database, we can use:
$ docker-compose down
--volumes
API Versions
It’s important to have an awareness of docker-compose API versions. In the docker-compose.yml file I used earlier, right at the top there is a version statement:
version: '3.3'
Docker Compose currently has 3 major API versions (v1, v2 and v3). Certain features are enabled or disabled depending on which one you use. Typically you will use the latest version – and if you are using docker-compose with Docker Swarm then you will need to use version 3+. You can learn more about Docker Compose API versions here.
Final Thoughts
Hopefully you should now have a view on what docker-compose is and how it can be used to build and run docker services. Look out for our docker-compose cheat sheet!
Learning Docker?
If you are starting out, then I highly recommend this book. Thirsty for more?
Then it’s time to take your Docker skills to the next level with this book (It’s my favorite). Also, check out my page on Docker Certification.