Docker Compose
### Compose Introduction
Compose is a tool for defining and running multi-container Docker applications. With Compose, you can use a YML file to configure all the services your application needs. Then, with a single command, you can create and start all the services from the YML file configuration.
If you are not familiar with YML file configuration, you can first read the (#).
The three steps for using Compose:
* Use a Dockerfile to define the environment for your application.
* Use docker-compose.yml to define the services that make up your application, so they can run together in an isolated environment.
* Finally, execute the docker-compose up command to start and run the entire application.
An example configuration for docker-compose.yml is as follows (refer to the following for configuration parameters):
## 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, we can download its binary package from Github to use. The address for the latest release is: [https://github.com/docker/compose/releases](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 a different version of Compose, replace v2.2.2.
> Docker Compose is hosted on GitHub, which can 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:
$ 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 if the installation was successful:
$ docker-compose version cker-compose version 1.24.1, build 4667896b
**Note**: For alpine, the following dependencies 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 at (#).
### 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 at (#).
* * *
## 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, which uses port 6379.
Create another file named requirements.txt in the composetest directory with the following content:
flask redis
### 2. Create the 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"]
**Explanation of Dockerfile content:**
* **FROM python:3.7-alpine**: Start building the image from the Python 3.7 image.
* **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 so that Python packages like MarkupSafe and SQLAlchemy can be compiled and accelerated.
* COPY requirements.txt requirements.txt RUN pip install -r requirements.txt
Copy requirements.txt and install Python dependencies.
* **COPY . .**: Copy the current directory . from the project to the working directory . in the image.
* **CMD ["flask", "run"]**: The default command for the container is: flask run.
### 3. Create docker-compose.yml
Create a file named docker-compose.yml in the test directory, 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**: The web service uses the image built from the Dockerfile in the current directory. Then, it binds the container and host to the exposed port 5000. This example service uses the default port 5000 of the Flask web server.
* **redis**: The redis service uses the public Redis image from Docker Hub.
### 4. Build and run your application with Compose commands
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
* * *
## yml Configuration Directive Reference
### version
Specifies which version of Compose this yml file complies with.
### build
Specifies 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
Alternatively, as an object with the path specified in the context, and an 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: The context path.
* dockerfile: Specifies the filename of the Dockerfile for building the image.
* args: Adds build arguments, which are environment variables accessible only during the build process.
* labels: Sets labels for the built image.
* target: For multi-stage builds, specifies which stage to build.
### cap_add, cap_drop
Adds or removes the kernel capabilities possessed by the container's host.
cap_add: - ALL # Enable all permissions cap_drop: - SYS_PTRACE # Disable ptrace permissions
### cgroup_parent
Specifies the parent cgroup group for the container, meaning it will inherit the resource limits of that group.
cgroup_parent: m-executor-abcd
### command
Overrides the default command for container startup.
command: ["bundle", "exec", "thin", "-p", "3000"]
### container_name
Specifies a custom container name instead of the generated default name.
container_name: my-web-container
### depends_on
Sets dependencies.
* docker-compose up: Starts services in dependency order. In the following example, db and redis are started before web.
* docker-compose up SERVICE: Automatically includes the dependencies of SERVICE. In the following example, docker-compose up web will also create and start db and redis.
* docker-compose stop: Stops services in dependency order. In the following example, web stops before db and redis.
version: "3.7" services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres
Note: The web service does not wait for redis db to fully start before starting.
### deploy
Specifies configuration related to the deployment and running of the service. 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 method for accessing cluster services.
endpoint_mode: vip # A virtual IP for the Docker cluster service. All requests reach the machines inside the cluster service through this virtual IP. endpoint_mode: dnsrr # DNS round-robin (DNSRR). All requests automatically rotate to obtain an IP address from the cluster IP list.
**labels**: Sets labels on the service. Labels on the container (configuration at the same level as deploy) can override labels under deploy.
**mode**: Specifies the mode in which the service is provided.
* **replicated**: Replicated service, replicates the specified service to machines in the cluster.
* **global**: Global service, the service will be deployed to every node in the cluster.
* Illustration: In the image below, the yellow squares represent the operation of replicated mode, and the gray squares represent the operation of global mode.
!(#)
**replicas**: When **mode** is replicated, this parameter is used to configure the specific number of nodes to run.
**resources**: Configures limits on server resource usage. For example, in the above example, it configures the percentage of CPU and memory usage required for the redis cluster to run. This avoids anomalies caused by excessive resource usage.
**restart_policy**: Configures how to restart the container when it exits.
* condition: Optional none, on-failure, or any (default: any).
* delay: Sets how long to wait before restarting (default: 0).
* max_attempts: The number of times to attempt to restart the container. After this number is exceeded, no further attempts are made (default: keep trying).
* window: Sets the timeout for container restart (default: 0).
**rollback_config**: Configures how to roll back the service if an update fails.
* parallelism: The number of containers to roll back at once. If set to 0, all containers will be rolled back simultaneously.
* delay: The time to wait between rolling back each group of containers (default: 0s).
* failure_action: What to do if the rollback fails. One of continue or pause (default: pause).
* monitor: The time to continuously monitor for failure after each container update (ns|us|ms|s|m|h) (default: 0s).
* max_failure_ratio: The failure rate that can be tolerated during rollback (default: 0).
* order: The order of operations during rollback. One of stop-first (serial rollback) or start-first (parallel rollback) (default: stop-first).
**update_config**: Configures how to update the service, useful for configuring rolling updates.
* parallelism: The number of containers to update at once.
* 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: The time to continuously monitor for failure after each container update (ns|us|ms|s|m|h) (default: 0s).
* max_failure_ratio: The failure rate that can be tolerated during the update process.
* order: The order of operations during rollback. One of stop-first (serial rollback) or start-first (parallel rollback) (default: stop-first).
**Note**: Only supported in V3.4 and higher versions.
### devices
Specifies a list of device mappings.
devices: - "/dev/ttyUSB0:/dev/ttyUSB0"
### dns
Custom DNS servers, can be a single value or a list of multiple values.
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 container's default entrypoint.
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
Adds environment variables from a file. Can be a single value or a list of multiple values.
env_file: .env
It 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. Any boolean values must be quoted to ensure the YML parser does not convert them to True or False.
environment: RACK_ENV: development SHOW: 'true'
### expose
Exposes ports, but does not map them to the host, only accessible by 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"
The above will create a mapping with IP addresses and hostnames in /etc/hosts inside this service's container:
162.242.195.82 somehost 50.31.209.229 otherhost
### healthcheck
Used to detect 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 for the container to run. 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
Logging configuration for the service.
driver: Specifies the logging driver for the service container, default is json-file. There are three options:
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 10 files
When the file limit is reached, old files will be automatically deleted.
Under the syslog driver, 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:" network_mode: "container:[container name/id]"
### networks
Configures the networks the container connects to, 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 corresponding container's service.
### restart
* no: The default restart policy, which does not restart the container under any circumstances.
* always: The container always restarts.
* on-failure: The container only restarts if it exits abnormally (exit status not 0).
* unless-stopped: The container always restarts when it exits, but does not consider containers that were already stopped when the Docker daemon started.
restart: "no" restart: always restart: on-failure restart: unless-stopped
Note: For swarm cluster mode, please use restart_policy instead.
### secrets
Stores 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
Modifies the default schema labels of the container.
security-optοΌ - label:user:USER # Sets the user label for the container - label:role:ROLE # Sets the role label for the container - label:type:TYPE # Sets the security policy label for the container - label:level:LEVEL # Sets the security level label for the container
### stop_grace_period
Specifies how long to wait before sending the SIGKILL signal to close the container if it cannot handle the SIGTERM (or any stop_signal) signal.
stop_grace_period: 1s # Wait 1 second stop_grace_period: 1m30s # Wait 1 minute 30 seconds
The default wait time is 10 seconds.
### stop_signal
Sets an alternative signal to stop the container. By default, SIGTERM is used.
The following example uses the SIGUSR1 signal instead of SIGTERM to stop the container.
stop_signal: SIGUSR1
### sysctls
Sets kernel parameters inside the container, can use 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
Mounts a temporary filesystem inside the container. Can be a single value or a list of multiple values.
tmpfs: /run tmpfs: - /run - /tmp
### ulimits
Overrides the container's default ulimit.
ulimits: nproc: 65535 nofile: soft: 20000 hard: 40000
### volumes
Mounts host data 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"
YouTip