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:
- Define your app's environment with a Dockerfile.
- Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
- Run
docker-compose up
to start and run your entire application.
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:
- FROM python:3.7-alpine: Start building the image from the Python 3.7 image.
- WORKDIR /code: Set the working directory to /code.
- ENV FLASKAPP app.py ENV FLASKRUN_HOST 0.0.0.0: Set environment variables for flask commands.
- RUN apk add --no-cache gcc musl-dev linux-headers: Install gcc to speed up compilation for Python packages like MarkupSafe and SQLAlchemy.
- COPY requirements.txt requirements.txt RUN pip install -r requirements.txt: Copy requirements.txt and install Python dependencies.
- COPY . .: Copy the current directory in the project to the working directory in the image.
- CMD ["flask", "run"]: The default command provided by the container is: flask run.
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.
- web: The web service uses the image built from the Dockerfile in the current directory. It binds the container and host to the exposed port 5000. This example service uses the default port 5000 for the Flask web server.
- redis: The redis service uses the public Redis image from Docker Hub.
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
- context: Context path.
- dockerfile: Specify the Dockerfile file name for building the image.
- args: Add build arguments, which are environment variables accessible only during the build process.
- labels: Set labels for the built image.
- target: Multi-stage builds, specify which stage to build.
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.
docker-compose up
: Start services in dependency order. In the following example, db and redis are started before web.version: '3' services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres
docker-compose up SERVICE
: Automatically includes the dependencies of SERVICE. In the following example,docker-compose up web
will also create and startdb
andredis
.docker-compose stop
: Stops services in the order of their dependencies. In the following example,web
stops beforedb
andredis
.version: "3.7" services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres
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.
- replicated: Replicates the service across the cluster machines.
- global: The service will be deployed on every node in the cluster.
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.
- condition: Optional values are
none
,on-failure
, orany
(default:any
). - delay: Time to wait before restarting (default: 0).
- max_attempts: Number of attempts to restart the container before giving up (default: infinite retries).
- window: Time to wait before considering the restart a failure (default: 0).
rollback_config: Configures how to roll back services in case of update failure.
- parallelism: Number of containers to roll back at once. If set to 0, all containers will roll back simultaneously.
- delay: Time to wait between rolling back groups of containers (default: 0s).
- failure_action: What to do if the rollback fails, either
continue
orpause
(default:pause
). - monitor: Duration to monitor after each container update to check if it failed (default: 0s).
- max_failure_ratio: Tolerable failure rate during rollback (default: 0).
- order: Order of operations during rollback, either
stop-first
(serial rollback) orstart-first
(parallel rollback) (default:stop-first
).
update_config: Configures how to update the service, useful for rolling updates.
- parallelism: Number of containers to update at once.
- delay: Time to wait between updating groups of containers.
- failure_action: What to do if the update fails, either
continue
,rollback
, orpause
(default:pause
). - monitor: Duration to monitor after each container update to check if it failed (default: 0s).
- max_failure_ratio: Tolerable failure rate during the update.
- order: Order of operations during the update, either
stop-first
(serial update) orstart-first
(parallel update) (default:stop-first
).
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
no
: The default restart policy, which never restarts the container.always
: The container always restarts.on-failure
: Restarts the container if it exits non-zero.unless-stopped
: Always restarts the container unless it was already stopped when the Docker daemon starts.restart: "no" restart: always restart: on-failure restart: unless-stopped
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"