Docker Compose

Docker Compose is a tool for defining and running multi-container Docker applications.

It uses YAML files to configure application’s services.

Service

Services are really just “containers in production.”. A Service runs one image and it defines ports, volumes, resource limitation, restart policy and replicas.

Installation

Instruction to install Compose is here

To install in Linux

1
2
3
4
5
6
7
8
# download latest version of Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# apply executable permissions to binary
sudo chmod +x /usr/local/bin/docker-compose

# test installation
docker-compose --version

Simple Example

Here is the example from Get Started with Docker Compose

Files Structure

1
2
3
4
5
composetest/
├── app.py
├── docker-compose.yml
├── Dockerfile
└── requirements.txt

app.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)


@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)

if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)

requirements.txt

1
2
flask
redis

Dockerfile

1
2
3
4
5
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

docker-compose.yml - defines two service, web and redis.

1
2
3
4
5
6
7
8
9
10
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: "redis:alpine"

use docker-compose up -d to start the services

Common docker-compose Commands

docker-compose up -d is the most used command to start service in the background

1
2
3
$ docker-compose up -d
Starting composetest_web_1 ... done
Starting composetest_redis_1 ... done

The default compose file to be used is docker-compose.yml, you can set alternative file using -f option.

1
docker-compose -f docker-compose.dev.yml  up -d

use docker-compose ps to list containers. If a container is not UP, you can usually use docker log command to see if there is error starting the container.

1
2
3
4
5
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------
composetest_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp
composetest_web_1 python app.py Up 0.0.0.0:5000->5000/tcp

Use docker-compose build command to rebuild the containers. This is useful after a change to a service

1
$ docker-compose build

use docker-compose stop to stop the containers without removing them. You can use docker-compose start to start the services again

1
2
3
$ docker-compose stop
Stopping composetest_web_1 ... done
Stopping composetest_redis_1 ... done

use docker-compose down to stop containers and removes containers, networks created by up. use -v to remove volumes and use --rmi to remove image

1
2
3
4
5
6
7
8
$ docker-compose down -v --rmi all
Stopping composetest_web_1 ... done
Stopping composetest_redis_1 ... done
Removing composetest_web_1 ... done
Removing composetest_redis_1 ... done
Removing network composetest_default
Removing image composetest_web
Removing image redis:alpine

Print out log messages from all container.

1
docker-compose logs -f --tail=0

Use docker help command to display the help menu.

For all the command reference, see docker-compose command-line Reference

docker-compose.yml file

Compose file has a version number. current version is version 3.

You can include the version number at the top of docker-compose.yml

1
version: '3'

Service Configuration

Then services list all the services to create.

build - usually a path to a build context. It can also specify context and optionally Dockerfile and args.

1
2
3
4
version: '3'
services:
web:
build: .

image - Specify the image to start the container from.

1
image: "redis:alpine"

environment - sets environment variable

1
2
3
4
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET

ports - specify ports(Host:Container)

1
2
3
ports:
- "5000:5000"
- "1234:1234"

volumes

1
2
volumes:
- .:/code

depends_on - sets dependency between services.

1
2
3
4
5
6
7
8
9
10
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres

Restart - sets restart policy. Default is “no”

1
2
3
4
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped

Volume Configuration

you can create named volumes in compose file

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
version: "3"

services:
db:
image: db
volumes:
- data-volume:/var/lib/db
backup:
image: backup-service
volumes:
- data-volume:/var/lib/backup/data

volumes:
data-volume:

Network Configuration

by default, Compose set up a bridge network for your app. You can customize it.

1
2
3
networks:
my_network:
driver: bridge

Other Examples

Running Postgres and Adminer

Two services will be started. postgres database and adminer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Use postgres/example user/password credentials
version: '3.1'

services:
db:
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: example

adminer:
image: adminer
restart: always
ports:
- 5555:8080

example from https://hub.docker.com/_/postgres

Wordpress

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
version: '3'

services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'

web:
image: wordpress
depends_on:
- db
volumes:
- wordpress_files:/var/www/html
ports:
- "80:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb

volumes:
wordpress_files:
db_data:

Reference