DOCKER: COMPOSE
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
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
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/initapp01:
image: centos
networks:
- dockernetwork
cap_add:
- NET_ADMIN
hostname: app01
privileged: true
command: /usr/sbin/initapp02:
image: centos
networks:
- dockernetwork
cap_add:
- NET_ADMIN
hostname: app02
privileged: true
command: /usr/sbin/initnetworks:
dockernetwork:
external: true
Bring up the stack via docker-compose up command.
Check for status of our ansible stack, should be UP and running!
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.
Once done with testing we can also easily clean up the whole stack via a single compose command i.e. docker-compose down.
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.
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.
Fill in the details and click Install WordPress and in a few mins, you will see the Wordpress Homepage. Voila! 👍
Cleanup
Cleanup is quick and easy with docker-compose, just use the “docker-compose down” command to remove the containers and the whole stack will be cleaned up.
$ docker-compose down
$ docker-compose down --volumes # remove volumes(data) as well
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