Easy Tutorial
❮ Docker Image Usage Docker Login Command ❯

Docker Compose

Introduction to Compose

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application's services. Then, with a single command, you create and start all the services from your configuration.

If you are not familiar with YAML file configuration, you can read the YAML Beginner's Guide first.

The three steps to use Compose:

Here is an example configuration for docker-compose.yml (configuration parameters are referenced below):

Example

# YAML configuration example
version: '3'
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
      - logvolume01:/var/log
    links:
      - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

Compose Installation

On Linux, you can download the binary package from Github for use. The latest release version address is: https://github.com/docker/compose/releases.

Run the following command to download the current stable version of Docker Compose:

$ sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

To install other versions of Compose, replace v2.2.2.

Docker Compose is stored on GitHub and may be unstable.

You can also install Docker Compose quickly by executing the following command:

curl -L https://get.daocloud.io/docker/compose/releases/download/v2.4.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

Apply executable permissions to the binary file:

$ sudo chmod +x /usr/local/bin/docker-compose

Create a symbolic link:

$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

Test the installation:

$ docker-compose version
docker-compose version 1.24.1, build 4667896b

Note: For alpine, the following dependency packages are required: py-pip, python-dev, libffi-dev, openssl-dev, gcc, libc-dev, and make.

macOS

Docker Desktop for Mac and Docker Toolbox already include Compose and other Docker applications, so Mac users do not need to install Compose separately. Docker installation instructions can be found in MacOS Docker Installation.

Windows PC

Docker Desktop for Windows and Docker Toolbox already include Compose and other Docker applications, so Windows users do not need to install Compose separately. Docker installation instructions can be found in Windows Docker Installation.


Usage

1. Preparation

Create a test directory:

$ mkdir composetest
$ cd composetest

Create a file named app.py in the test directory and copy and paste the following content:

composetest/app.py File Code

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)

In this example, redis is the hostname of the redis container on the application network, using port 6379.

Create another file named requirements.txt in the composetest directory with the following content:

flask
redis

2. Create Dockerfile

In the composetest directory, create a file named Dockerfile with the following content:

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]

Dockerfile Content Explanation:

3. Create docker-compose.yml

Create a file named docker-compose.yml in the test directory and paste the following content:

docker-compose.yml Configuration File

# YAML configuration
version: '3'
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

This Compose file defines two services: web and redis.

4. Build and Run Your App with Compose

In the test directory, execute the following command to start the application:

docker-compose up

If you want to run the service in the background, you can add the -d parameter:

docker-compose up -d

YAML Configuration Directive Reference

version

Specify the version of compose that this YAML file adheres to.

build

Specify the context path for building the image:

For example, for the webapp service, specify the image built from the context path ./dir/Dockerfile:

version: "3.7"
services:
  webapp:
    build: ./dir

Or, as an object with the path specified in the context, and optional Dockerfile and args:

version: "3.7"
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate
      args:
        buildno: 1
      labels:
        - "com.example.description=Accounting webapp"
        - "com.example.department=Finance"
        - "com.example.label-with-empty-value"
      target: prod

cap_add, cap_drop

Add or remove kernel capabilities of the container on the host.

cap_add:
  - ALL # Enable all permissions

cap_drop:
  - SYS_PTRACE # Disable ptrace permission

cgroup_parent

Specify the parent cgroup for the container, inheriting the resource limits of that group.

cgroup_parent: m-executor-abcd

command

Override the default command for the container.

command: ["bundle", "exec", "thin", "-p", "3000"]

container_name

Specify a custom container name instead of the default generated name.

container_name: my-web-container

depends_on

Set dependencies.

Note: The web service will not wait for redis and db to be fully started before starting itself.

deploy

Specifies configuration related to the deployment and running of services. This is only useful in swarm mode.

version: "3.7"
services:
  redis:
    image: redis:alpine
    deploy:
      mode: replicated
      replicas: 6
      endpoint_mode: dnsrr
      labels:
        description: "This redis service label"
      resources:
        limits:
          cpus: '0.50'
          memory: 50M
        reservations:
          cpus: '0.25'
          memory: 20M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s

Optional parameters:

endpoint_mode: The way to access the cluster service.

endpoint_mode: vip
# Docker assigns a virtual IP for the cluster service. All requests go through this virtual IP to reach the service.
endpoint_mode: dnsrr
# DNS Round Robin (DNSRR). Requests are automatically round-robin to the list of cluster IPs.

labels: Sets labels on the service. Labels on the container (at the same level as deploy) can override those under deploy.

mode: Specifies the mode of service provision.

Diagram: Yellow squares represent the running state of replicated mode, and gray squares represent the running state of global mode.

replicas: When mode is replicated, this parameter configures the number of nodes to run.

resources: Configures resource usage limits, such as CPU percentage and memory usage in the example, to prevent excessive resource consumption.

restart_policy: Configures how to restart containers when they exit.

rollback_config: Configures how to roll back services in case of update failure.

update_config: Configures how to update the service, useful for rolling updates.

Note: Supported in version 3.4 and later.

devices

Specifies a list of device mappings.

devices:
  - "/dev/ttyUSB0:/dev/ttyUSB0"

dns

Custom DNS servers, can be a single value or a list.

dns: 8.8.8.8

dns:
  - 8.8.8.8
  - 9.9.9.9

dns_search

Custom DNS search domains, can be a single value or a list.

dns_search: example.com

dns_search:
  - dc1.example.com
  - dc2.example.com

entrypoint

Overrides the default entrypoint of the container.

entrypoint: /code/entrypoint.sh

Can also be in the following format:

entrypoint:
    - php
    - -d
    - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
    - -d
    - memory_limit=-1
    - vendor/bin/phpunit

env_file

Adds environment variables from a file. Can be a single value or a list.

env_file: .env

Can also be in list format:

env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env

environment

Adds environment variables. You can use arrays or dictionaries, and any boolean values need to be quoted to ensure the YML parser does not convert them to True or False.

environment:
  RACK_ENV: development
  SHOW: 'true'

expose

Exposes ports without mapping to the host, only accessible to connected services.

Only internal ports can be specified as parameters:

expose:
 - "3000"
 - "8000"

extra_hosts

Adds hostname mappings. Similar to docker client --add-host.

extra_hosts:
 - "somehost:162.242.195.82"
 - "otherhost:50.31.209.229"

This will create a mapping in the internal container's /etc/hosts with the IP address and hostname:

162.242.195.82  somehost
50.31.209.229   otherhost

healthcheck

Used to check if the docker service is running healthily.

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"] # Set the detection program
  interval: 1m30s # Set the detection interval
  timeout: 10s # Set the detection timeout
  retries: 3 # Set the number of retries
  start_period: 40s # After startup, how many seconds to start the detection program

image

Specifies the image to run the container. Any of the following formats can be used:

image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd # Image id

logging

Configuration for the service's logging.

driver: Specifies the logging driver for the service container, with the default being json-file. Three options are available:

driver: "json-file"
driver: "syslog"
driver: "none"

Only under the json-file driver, the following parameters can be used to limit the number and size of logs:

logging:
  driver: json-file
  options:
    max-size: "200k" # Single file size is 200k
    max-file: "10" # Maximum of 10 files

When the file limit is reached, old files will be automatically deleted.

Under the syslog driver, the syslog-address can be used to specify the log receiving address.

logging:
  driver: syslog
  options:
    syslog-address: "tcp://192.168.0.42:123"

network_mode

Sets the network mode.

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

networks

Configures the networks to which the container connects, referencing entries under the top-level networks.

services:
  some-service:
    networks:
      some-network:
        aliases:
         - alias1
      other-network:
        aliases:
         - alias2
networks:
  some-network:
    # Use a custom driver
    driver: custom-driver-1
  other-network:
    # Use a custom driver which takes special options
    driver: custom-driver-2

aliases: Other containers on the same network can use the service name or this alias to connect to the service.

restart

Note: For swarm cluster mode, use restart_policy instead.

secrets

Stores sensitive data, such as passwords:

version: "3.1"
services:
  mysql:
    image: mysql
```yaml
environment:
  MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret
secrets:
  - my_secret

secrets:
  my_secret:
    file: ./my_secret.txt

security_opt

Modify the container's default schema label.

security_opt:
  - label:user:USER   # Set the container's user label
  - label:role:ROLE   # Set the container's role label
  - label:type:TYPE   # Set the container's security policy label
  - label:level:LEVEL  # Set the container's security level label

stop_grace_period

Specify how long to wait before sending a SIGKILL signal to the container if it cannot process SIGTERM (or any signal specified by stop_signal).

stop_grace_period: 1s # Wait for 1 second
stop_grace_period: 1m30s # Wait for 1 minute 30 seconds

The default wait time is 10 seconds.

stop_signal

Set an alternative signal to stop the container. By default, SIGTERM is used.

The following example uses SIGUSR1 instead of SIGTERM to stop the container.

stop_signal: SIGUSR1

sysctls

Set kernel parameters within the container. This can be done using an array or dictionary format.

sysctls:
  net.core.somaxconn: 1024
  net.ipv4.tcp_syncookies: 0

sysctls:
  - net.core.somaxconn=1024
  - net.ipv4.tcp_syncookies=0

tmpfs

Mount a temporary file system inside the container. This can be a single value or a list of multiple values.

tmpfs: /run

tmpfs:
  - /run
  - /tmp

ulimits

Override the default ulimits for the container.

ulimits:
  nproc: 65535
  nofile:
    soft: 20000
    hard: 40000

volumes

Mount host volumes or files into the container.

version: "3.7"
services:
  db:
    image: postgres:latest
    volumes:
      - "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
      - "/localhost/data:/var/lib/postgresql/data"
❮ Docker Image Usage Docker Login Command ❯