English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Docker Compose

Compose Introduction

Compose is a tool used to define and run multi-container Docker applications. Through Compose, you can use YML files to configure all the services required by the application. Then, with a single command, you can create and start all services from the YML file configuration.

Three steps used by Compose:

  • Define the environment of the application using Dockerfile.

  • Use docker-compose.yml defines the services that make up the application, so that they can run together in an isolated environment.

  • Finally, execute docker-Use the compose up command to start and run the entire application.

docker-The following is an example of the configuration of compose.yml (configuration parameters are referred to below):

# 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

Linux

On Linux, we can download its binary package from Github to use, the address of the latest released version: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/1.24.1/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose

To install other versions of Compose, replace 1.24.1.

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 whether the installation is successful:

$ docker-compose --version
cker-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

Mac Docker Desktop Edition 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

Windows Docker Desktop Edition 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.

Use

1、Prepare

Create a test directory:

$ mkdir composetest
$ cd composetest

Create a file named app.py in the test directory 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.
'.format(count)

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

In the composetest directory, create another file named requirements.txt with the following content:

flask
redis

2Create Dockerfile file

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:

  • FROM python:3.7-alpine: From Python 3.7 : Start building the image from the Python

  • WORKDIR /code: Set the working directory to /code.

  • ENV FLASK_APP app.py
    ENV FLASK_RUN_HOST 0.0.0.0

    Set the environment variables used by the flask command.

  • RUN apk add --no-cache gcc musl-dev linux-headers: Install gcc to allow Python packages like MarkupSafe and SQLAlchemy to compile and accelerate.

  • COPY requirements.txt requirements.txt
    RUN pip install -r requirements.txt

    Copy requirements.txt and install Python dependencies.

  • COPY . .: Copy the current directory of the . project to the working directory of the . image.

  • CMD ["flask", "run"]: The default execution command provided by the container is: flask run.

3Create docker-compose.yml

Create a directory named docker in the test directory-The file compose.yml, then 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.

  • web: This web service uses the image built from the current directory of the Dockerfile. Then, it binds the container and host to the exposed port 5000. This example service uses the default port of the Flask web server 5000 .

  • redis: This redis service uses the public Redis image from Docker Hub.

4Using Compose commands to build and run your application

Execute the following command in the test directory to start the application:

docker-compose up

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

docker-compose up -d

Reference for yml configuration instructions

version

Specify which version of compose this yml conforms to.

build

Specify the context path for building the image:

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

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

Alternatively, as an object with the path specified in the context, and optionally 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
  • context: Context path.

  • dockerfile: Specify the Dockerfile filename for building the image.

  • args: Add build parameters, which are only accessible in the build process as environment variables.

  • labels: Set the labels for building the image.

  • target: Multi-layer build, can specify which layer to build.

cap_add, cap_drop

Add or delete the host kernel features owned by the container.

cap_add:
  - ALL # Enable all permissions
cap_drop:
  - SYS_PTRACE # Disable ptrace permission

cgroup_parent

Specifying the parent cgroup group for the container means inheriting the resource limits of that group.

cgroup_parent: m-executor-abcd

command

Override the default command for container startup.

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

container_name

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

container_name: my-web-container

depends_on

Set dependencies.

  • docker-compose up: Start services in order of dependencies. In the following example, db and redis are started first, followed by web.

  • docker-compose up SERVICE: Automatically include the dependencies of SERVICE. In the following example, docker-compose up web will also create and start db and redis.

  • docker-compose stop: Stop services in order of dependencies. In the following example, web is stopped before db and redis.

version: "3.7"
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

Note: The web service will not wait for the redis db to fully start before starting.

deploy

Specify the configuration related to the deployment and operation of the service. It 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

Can select parameters:

endpoint_mode: The way to access the cluster service.

endpoint_mode: vip 
# Docker cluster service provides a virtual IP to the outside. All requests will reach the internal machines of the cluster service through this virtual IP.
endpoint_mode: dnsrr
# DNS round-robin (DNSRR). All requests are automatically round-robin to obtain an IP address from the cluster IP list.

labelsSet labels on the service. You can override the labels under deploy with labels on the container (deploy同级配置).

modeThe mode provided by the specified service.

  • replicatedReplicated service, replicate the specified service to the machines in the cluster.

  • globalGlobal service, the service will be deployed to each node of the cluster.

  • Illustration: In the figure below, the yellow blocks represent the running status of the replicated mode, and the gray blocks represent the running status of the global mode.

replicas: mode For replicated, you need to use this parameter to configure the specific number of nodes to run.

resourcesHow to configure the resource usage limits of the server, for example, in the above instance, configure the percentage of cpu and memory usage required for the redis cluster to run. Avoid using too many resources to cause exceptions.

restart_policyHow to restart containers when exiting containers.

  • condition: Optional none, on-failure or any (default value: any).

  • delay: Set how long to wait after restart (default value: 0).

  • max_attempts: The number of times to try to restart a container. If exceeded, no more attempts will be made (default value: retry indefinitely).

  • window: Set the container restart timeout time (default value: 0).

rollback_configHow to configure the rollback of services in case of update failure.

  • parallelism: The number of containers to roll back at one time. If set to 0, all containers will rollback simultaneously.

  • delay: The time to wait between rolling back each container group (default is 0s).

  • failure_action: What to do if the rollback fails. One of continue or pause (default pause).

  • monitor: Continuously observe the time (ns|us|ms|s|m|h) after each container update to see if it has failed (default is 0s).

  • max_failure_ratio: The allowable failure rate during rollback (default is 0).

  • order: operation sequence during rollback. One of stop-first (serial rollback), or start-first (parallel rollback) (default stop-first )

update_configHow to configure the update of services, which is very useful for rolling updates.

  • parallelism: The number of containers to update at one time.

  • delay: The time to wait between updating a group of containers.

  • failure_action: What to do if the update fails. One of continue, rollback, or pause (default: pause).

  • monitor: Continuously observe the time (ns|us|ms|s|m|h) after each container update to see if it has failed (default is 0s).

  • max_failure_ratio: The failure rate that can be tolerated during the update process.

  • order: operation sequence during rollback. One of stop-first (serial rollback), or start-first (parallel rollback) (default stop-first).

Note: Only supports V3.4 and higher versions.

devices

Specify the device mapping list.

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

dns

Customize the DNS server, which can be a single value or multiple values in a list.

dns: 8.8.8.8
dns:
  - 8.8.8.8
  - 9.9.9.9

dns_search

Customize the DNS search domain. It can be a single value or a list.

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

entrypoint

Override the default entrypoint of the container.

entrypoint: /code/entrypoint.sh

It 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

Add environment variables from a file. It can be a single value or multiple values in a list.

env_file: .env

It can also be in list format:

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

environment

Add environment variables. You can use an array or dictionary, any boolean value, and boolean values need to be quoted to ensure that the YML parser does not convert them to True or False.

environment:
  RACK_ENV: 'development'
  SHOW: 'true'

 

expose

Expose ports but not mapped to the host machine, only accessible by the connected service.

Only internal ports can be specified as parameters:

expose:
 - "3000"
 - "8000"

extra_hosts

Add hostname mapping. Similar to docker client --add-host.

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

The above will be in the internal container of this service /etc/hosts create a mapping relationship between 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", "-", "http://localhost"] # Set the detection program
  interval: 1m30s # Set the detection interval
  timeout: 10s # Set the detection timeout time
  retries: 3 # Set the number of retries
  start_period: 40s # How many seconds after startup to start the detection program

image

Specify the image to be run by the container. The following formats are all acceptable:

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

logging

Service logging configuration.

driver: Specify the logging driver for the service container, the default value is json-file. There are three options

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

Only in json-Under the file driver, you can use the following parameters to limit the number and size of logs.

logging:
  driver: "json"-file
  options:
    max-size: "200k"# Size of a single file is200k
    max-file: "10"# Maximum10files

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

Under the syslog driver, you can use syslog-The address specifies the log receiving address.

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

network_mode

Set the network mode.

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

networks

Configure the network for the container connection, referencing the 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 connect to the corresponding container's service using the service name or this alias.

restart

  • no: This is the default restart policy and the container will not be restarted under any circumstances.

  • always: The container is always restarted.

  • on-failure: The container will only restart if it exits abnormally (the exit status is not 0).

  • unless-stopped: Always restart the container when the container exits, but does not consider the container that was stopped when the Docker daemon started.

restart: "no"
restart: always
restart: on-failure
restart: unless-stopped

Note: In swarm cluster mode, please use restart_policy instead.

secrets

Store sensitive data, such as passwords:

version: "3.1"
services:
mysql:
  image: mysql
  environment:
    MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret
  secrets:
    - my_secret
secrets:
  my_secret:
    file: ./my_secret.txt

security_opt

Modify the default schema tag of the container.

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 the SIGKILL signal to close the container if the container cannot handle SIGTERM (or any stop_signal signal).

stop_grace_period: 1s # Wait 1 seconds
stop_grace_period: 1m30s # Wait 1 minutes 30 seconds

The default waiting time is 10 seconds.

stop_signal

Set the replacement signal for stopping the container. The default is SIGTERM.

The following example uses SIGUSR1 Replace the signal SIGTERM to stop the container.

stop_signal: SIGUSR1

sysctls

Set kernel parameters inside the container, which can be in 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

Install a temporary filesystem inside the container. It can be a single value or a list of multiple values.

tmpfs: /run
tmpfs:
  - /run
  - /tmp

ulimits

Override the default ulimit of the container.

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

volumes

Mount the host's data volume or file to 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"