DOCKER: COMPOSE

Avishek Roy
teckdevops
Published in
6 min readApr 22, 2020

A Docker tool to run multi-container Docker applications.

Compose is the next leap after docker run in the world of containerization. It provides an option to define and run multi-container applications within a Docker, it also provides a method to group all project-related containers, manage, run and control them via a single easy to a readable YAML file.

PS: Visit Yaml official site here for more insights on YAML syntax

Pre-requisites:

  • Docker Engine (Installed)
  • YAML basics

For windows and mac, compose comes bundled with docker application and for Linux, the same can be downloaded from the docker-compose release page i.e. docker-compose install.

Usage

docker-compose preferably used to manage dev and automated test environments as it helps to spin up whole application stack via an easily manageable docker-compose YAML file and as soon as we are done with tests the whole stack can be easily cleaned up via a single command.

Similar to docker run, compose also support an identical set of commands like ps/top/rm/stop/start, etc.

docker-compose [-f <arg>…] [options] [COMMAND] [ARGS…]
docker-compose -h| — help

## Sample commands-> teckdevOps$ docker-compose up-> teckdevOps$ docker-compose up -d-> teckdevOps$ docker-compose -f ansible-docker-compose.yml up -d

Overview

To start with docker-compose minimal we must have a YAML file containing all services, required bits & pieces to run our application stack and Docker engine to execute compose commands to bring up the application e.g. docker-compose up.

So, let us see some of the samples, compose files to get a brief idea and to how things work!

Examples

To start off, we will go through some simple setups like creating a web application/test setup and as we proceed we will explore some complex sample application stacks.

1. Ngnix

First, we will convert a sample docker run command(as we saw on our DOCKER RUN tutorial) into a compose file so that to see how easily we can convert docker run to compose!

Below is sample docker run command to run a nginx container i.e. with parameters like port (8888:80), name of the container(webserver), run it in the background(detach mode) and image to use(Nginx).

Docker Run
$ docker run --publish 8888:80 --name webserver --detach nginx

and here is the docker-compose conversion i.e. docker-compose.yml file.

Docker Compose
teckdevOps$ cat docker-compose.yml

version: "3.3" # docker compose file format version
services: # services to run
webserver: # name of the service
image: nginx # image to be used for container
ports: # ports to be used for container
- 8888:80 # specific ports definition

Now the second step is to run the container service/s as we defined in our compose YAML file via executing compose commands(using docker client).

teckdevOps$ docker-compose up -d
Creating network "nginx_default" with the default driver
Creating nginx_webserver_1 ... done
docker-compose up

The above command will bring up the whole stack as defined in the compose file. we use “-d” to run our stack into the background and its usage is the same as of “-d” mode in docker run. Now run below command to list containers.

teckdevOps$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------
nginx_webserver_1 nginx -g daemon off; Up 0.0.0.0:8888->80/tcp
docker-compose ps

The last thing is to access the nginx url i.e. 192.168.99.100:8888.

PS: Please change/update the above IP with your docker host IP and the same can be found via following command “docker-machine IP”.

2. Ansible test setup via docker-compose

In our next example, we will be going to set up the Ansible test environment that is usually required for playbook validation/checks. Earlier here we created an ansible master-slave set up i.e. created a custom docker network and 3 containers via docker run command line. Let’s now convert the same to a docker-compose YAML file.

Docker RUNteckdevOps$ docker network create dockernetworkteckdevOps$ docker run -d -t --name master_ansible --cap-add=NET_ADMIN -h controlnode --privileged=true --network dockernetwork centos /usr/sbin/init

teckdevOps$ docker run -d -t --name app01 --cap-add=NET_ADMIN -h app01 --privileged=true --network dockernetwork centos /usr/sbin/init

teckdevOps$ docker run -d -t --name app02 --cap-add=NET_ADMIN -h app02 --privileged=true --network dockernetwork centos /usr/sbin/init

Docker Compose 👇

teckdevOps$ cat docker-compose.yml
version: "3.3"
services:
master_ansible:
image: centos
networks:
- dockernetwork
cap_add:
- NET_ADMIN
hostname: controlnode
privileged: true
command: /usr/sbin/init
app01:
image: centos
networks:
- dockernetwork
cap_add:
- NET_ADMIN
hostname: app01
privileged: true
command: /usr/sbin/init
app02:
image: centos
networks:
- dockernetwork
cap_add:
- NET_ADMIN
hostname: app02
privileged: true
command: /usr/sbin/init
networks:
dockernetwork:
external: true

Bring up the stack via docker-compose up command.

docker-compose up

Check for status of our ansible stack, should be UP and running!

docker-compose ps
docker ps

Install and setup ssh on all three containers and ansible on the control node so that to run a few tests. Refer to link, section 2(ansible setup) for more information.

Try ansible commands via the control node.

ansible test

Once done with testing we can also easily clean up the whole stack via a single compose command i.e. docker-compose down.

docker-compose down
Cleanup

Done!

3. WordPress setup via docker/docker-compose

Next, up on the list is to set up Wordpress using docker-compose. Wordpress is a content management tool widely used for websites and online blogging portals. For our docker setup, we mainly require 2 images i.e. Wordpress image and MySQL image.

teckdevOps$ cat docker-compose.yml
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
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: {}

Now, run docker-compose up -d , that will pulls the needed Docker images if not already available on a local machine, and start the WordPress and database containers, as shown below.

docker-compose up
docker-compose ps

Next, run http://MACHINE_VM_IP:8000 in a web browser (or http://localhost:8000) and we should see the WordPress install page on the port 8000 of Docker Host, and Wordpress is now ready to be set up as an administrator.

WordPress Admin

Fill in the details and click Install WordPress and in a few mins, you will see the Wordpress Homepage. Voila! 👍

Wordpress Homepage

Cleanup

Cleanup is quick and easy with docker-compose, just use the “docker-compose downcommand to remove the containers and the whole stack will be cleaned up.

$ docker-compose down
$ docker-compose down --volumes # remove volumes(data) as well
docker-compose down

Addendum: Docker Troubleshooting

While starting up or running with docker-compose one might get an error related to SSL/TLS error. Below are the steps to quickly rectify a common error which you might face while running the docker-compose commands.

teckdevOps$ docker-compose -f docker-compose-nginx.yml up -d
ERROR: SSL error: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:661)

teckdevOps$ export COMPOSE_TLS_VERSION=TLSv1_2

teckdevOps$ docker-compose -f docker-compose-nginx.yml up -d
Creating network "desktop_default" with the default driver
Creating desktop_webserver_1 ... done

Cheers!

— A blog by teckdevOps

--

--