Compose 的定位是“定义和运行多个 Docker 容器的应用,其前身是开源项目 Fig ,目前仍然兼容 Fig 格式的模本文件。**Compose 项目由 Python 编写.**之前我们知道,使用 Dockerfile 模板文件可以让用户很方便地定义 一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况,
列如部署一个web服务,可能包括mysql,redis,负载均衡等等!
Compose 允许用户通过一个单独的docker-compose.yml模板文件( YAML 格式)来定义 一组相关联的应用容器为一个项目
- 服务( service ):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例
- 项目 project ):由一组关联的应用容器组成的 个完整业务单元,在docker-compose.yml 文件中定义
Compose 的默认管理对象是项目,可通过子命令对项目中的一组容器进行便捷的生命周期管理
官网参考:https://docs.docker.com/compose/install/
- 下载最新版的docker-compose文件
curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
- 若是github访问太慢,可以用daocloud下载
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
- 添加可执行权限
chmod +x /usr/local/bin/docker-compose
- 测试
docker-compose --version docker-compose version 1.25.1, build a82fef07pip 安装
yum install epel-release -y pip install --upgrade pip yum install -y python-pip pip install --upgrade pip docker-compose --version应用 Compose 的案例
可以参照官方案例:https://docs.docker.com/compose/gettingstarted/
编写一个 Python Web 案例,应用 Compose 编排服务 案例包含两个容器 Python Web 容器、 Redis 数据库容器
- 创建 composeapp 目录
mkdir composeapp cd composeapp
- 编写 Python 程序
touch Dockerfile
touch app.py
cat app.py
from flask import Flask
from redis import Redis
import os
app=Flask(__name__)
redis=Redis(host='redis',port=6379)
@app.route('/')
def hello():
redis.incr('hits')
return 'Hello Docker Book reader! I have been seen {0} times'.format(redis.get('hits'))
if __name__=="__main__":
app.run(host='0.0.0.0',debug=True)
- 创建 Python 的依赖包描述文件
cat requirements.txt falsk redis
- 编写 Python Web 容器的镜像 Dockerfile 文件
cat Dockerfile FROM python:3.7 MAINTAINER lesheng <123465212@qq.com> ENV REFRESHED_AT 2016-08-01 ADD ./ /composeapp WORKDIR /composeapp RUN pip install -r requirements.txt
- 构建镜像
[root@localhost composeapp]# docker build -t compose_test . Sending build context to Docker daemon 4.096kB Step 1/6 : FROM python:3.7 ---> ad37de9b03ef Step 2/6 : MAINTAINER lesheng <123465212@qq.com> ---> Using cache ---> 5c6bcd19da5d Step 3/6 : ENV REFRESHED_AT 2016-08-01 ---> Using cache ---> 328dce5aded7 Step 4/6 : ADD ./ /composeapp ---> d9f8b098b9ca Step 5/6 : WORKDIR /composeapp ---> Running in a16217af77d9 Removing intermediate container a16217af77d9 ---> c11d0a64af02 Step 6/6 : RUN pip install -r requirements.txt ---> Running in 9ff9ba40142b Collecting flask Downloading Flask-2.1.2-py3-none-any.whl (95 kB) Collecting redis Downloading redis-4.2.2-py3-none-any.whl (226 kB) Collecting itsdangerous>=2.0 Downloading itsdangerous-2.1.2-py3-none-any.whl (15 kB) Collecting Jinja2>=3.0 Downloading Jinja2-3.1.2-py3-none-any.whl (133 kB) Collecting importlib-metadata>=3.6.0 Downloading importlib_metadata-4.11.3-py3-none-any.whl (18 kB) Collecting click>=8.0 Downloading click-8.1.3-py3-none-any.whl (96 kB) Collecting Werkzeug>=2.0 Downloading Werkzeug-2.1.2-py3-none-any.whl (224 kB) Collecting packaging>=20.4 Downloading packaging-21.3-py3-none-any.whl (40 kB) Collecting async-timeout>=4.0.2 Downloading async_timeout-4.0.2-py3-none-any.whl (5.8 kB) Collecting deprecated>=1.2.3 Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB) Collecting typing-extensions Downloading typing_extensions-4.2.0-py3-none-any.whl (24 kB) Collecting wrapt<2,>=1.10 Downloading wrapt-1.14.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (75 kB) Collecting zipp>=0.5 Downloading zipp-3.8.0-py3-none-any.whl (5.4 kB) Collecting MarkupSafe>=2.0 Downloading MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25 kB) Collecting pyparsing!=3.0.5,>=2.0.2 Downloading pyparsing-3.0.8-py3-none-any.whl (98 kB) Installing collected packages: zipp, typing-extensions, wrapt, pyparsing, MarkupSafe, importlib-metadata, Werkzeug, packaging, Jinja2, itsdangerous, deprecated, click, async-timeout, redis, flask Successfully installed Jinja2-3.1.2 MarkupSafe-2.1.1 Werkzeug-2.1.2 async-timeout-4.0.2 click-8.1.3 deprecated-1.2.13 flask-2.1.2 importlib-metadata-4.11.3 itsdangerous-2.1.2 packaging-21.3 pyparsing-3.0.8 redis-4.2.2 typing-extensions-4.2.0 wrapt-1.14.0 zipp-3.8.0 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv WARNING: You are using pip version 21.2.4; however, version 22.0.4 is available. You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command. Removing intermediate container 9ff9ba40142b ---> 7ae0ef0ef0d6 Successfully built 7ae0ef0ef0d6 Successfully tagged compose_test:latest
- 构建 Docker Compose yml 文件,即 docker-compose. yml 文件
web: image: compose_test command: python app.py ports: - "5000:5000" volumes: - ./:/composeapp links: - redis redis: image: redis
- 切换到composeapp 目录下,以 compose 的方式运行
docker-compose up Starting composeapp_redis_1 ... done Starting composeapp_web_1 ... done Attaching to composeapp_redis_1, composeapp_web_1 redis_1 | 1:C 01 May 2022 17:37:49.197 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo redis_1 | 1:C 01 May 2022 17:37:49.197 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started redis_1 | 1:C 01 May 2022 17:37:49.197 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf redis_1 | 1:M 01 May 2022 17:37:49.198 * monotonic clock: POSIX clock_gettime redis_1 | 1:M 01 May 2022 17:37:49.200 * Running mode=standalone, port=6379. redis_1 | 1:M 01 May 2022 17:37:49.200 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. redis_1 | 1:M 01 May 2022 17:37:49.200 # Server initialized redis_1 | 1:M 01 May 2022 17:37:49.200 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. redis_1 | 1:M 01 May 2022 17:37:49.201 * Loading RDB produced by version 6.2.6 redis_1 | 1:M 01 May 2022 17:37:49.201 * RDB age 34 seconds redis_1 | 1:M 01 May 2022 17:37:49.201 * RDB memory usage when created 0.77 Mb redis_1 | 1:M 01 May 2022 17:37:49.201 # Done loading RDB, keys loaded: 0, keys expired: 0. redis_1 | 1:M 01 May 2022 17:37:49.201 * DB loaded from disk: 0.000 seconds redis_1 | 1:M 01 May 2022 17:37:49.201 * Ready to accept connections web_1 | * Serving Flask app 'app' (lazy loading) web_1 | * Environment: production web_1 | WARNING: This is a development server. Do not use it in a production deployment. web_1 | Use a production WSGI server instead. web_1 | * Debug mode: on web_1 | * Running on all addresses (0.0.0.0) web_1 | WARNING: This is a development server. Do not use it in a production deployment. web_1 | * Running on http://127.0.0.1:5000 web_1 | * Running on http://172.17.0.3:5000 (Press CTRL+C to quit) web_1 | * Restarting with stat web_1 | * Debugger is active! web_1 | * Debugger PIN: 101-953-261 web_1 | 172.17.0.1 - - [01/May/2022 17:39:02] "GET / HTTP/1.1" 200 - web_1 | 172.17.0.1 - - [01/May/2022 17:39:02] "GET /favicon.ico HTTP/1.1" 404 - web_1 | 172.17.0.1 - - [01/May/2022 17:39:06] "GET / HTTP/1.1" 200 -
- 测试
指定本 yml 依从的 compose 哪个版本制定的。
- build
-指定为构建镜像上下文路径:
例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:
version: "3.7"
services:
webapp:
build: ./dir
或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile 和 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
command
覆盖容器启动的默认命令。
command: ["bundle", "exec", "thin", "-p", "3000"]
- container_name
指定自定义容器名称,而不是生成的默认名称。
container_name: my-web-container
- depends_on
设置依赖关系。- docker-compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis ,才会启动 web。
- docker-compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中, docker-compose up web 还将创建并启动 db 和 redis。
- docker-compose stop :按依赖关系顺序停止服务。在以下示例中,web 在 db 和 redis 之前停止。
version: "3.7"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
deploy
指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用。
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
endpoint_mode
访问集群服务的方式
endpoint_mode: vip # Docker 集群服务一个对外的虚拟 ip。所有的请求都会通过这个虚拟 ip 到达集群服务内部的机器。 endpoint_mode: dnsrr # DNS 轮询(DNSRR)。所有的请求会自动轮询获取到集群 ip 列表中的一个 ip 地址。labels
在服务上设置标签。可以用容器上的 labels(跟 deploy 同级的配置) 覆盖 deploy 下的 labels
dns自定义 DNS 服务器,可以是单个值或列表的多个值。
dns: 8.8.8.8 dns: - 8.8.8.8 - 9.9.9.9entrypoint
覆盖容器默认的 entrypoint。
entrypoint: /code/entrypoint.sh
也可以是以下格式:
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
从文件添加环境变量。可以是单个值或列表的多个值。
env_file: .env
也可以是列表格式:
env_file: - ./common.env - ./apps/web.env - /opt/secrets.envenvironment
添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。
environment: RACK_ENV: development SHOW: 'true'expose
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数:
expose: - "3000" - "8000"extra_hosts
添加主机名映射。类似 docker client --add-host。
extra_hosts: - "somehost:162.242.195.82" - "otherhost:50.31.209.229"
以上会在此服务的内部容器中 /etc/hosts 创建一个具有 ip 地址和主机名的映射关系:
162.242.195.82 somehost 50.31.209.229 otherhosthelthcheck
用于检测 docker 服务是否健康运行。
healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序 interval: 1m30s # 设置检测间隔 timeout: 10s # 设置检测超时时间 retries: 3 # 设置重试次数 start_period: 40s # 启动后,多少秒开始启动检测程序image
指定容器运行的镜像。以下格式都可以:
image: redis image: ubuntu:14.04 image: tutum/influxdb image: example-registry.com:4000/postgresql image: a4bc65fd # 镜像idlogging
服务的日志记录配置。
driver:指定服务容器的日志记录驱动程序,默认值为json-file。有以下三个选项
driver: "json-file" driver: "syslog" driver: "none"
仅在 json-file 驱动程序下,可以使用以下参数,限制日志得数量和大小。
logging:
driver: json-file
options:
max-size: "200k" # 单个文件大小为200k
max-file: "10" # 最多10个文件
当达到文件限制上限,会自动删除旧得文件。
syslog 驱动程序下,可以使用 syslog-address 指定日志接收地址。
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
network_mode
设置网络模式。
network_mode: "bridge" network_mode: "host" network_mode: "none" network_mode: "service:[service name]" network_mode: "container:[container name/id]"
networks
配置容器连接的网络,引用顶级 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
restart
- **no**:是默认的重启策略,在任何情况下都不会重启容器。 - always:容器总是重新启动。 - on-failure:在容器非正常退出时(退出状态非0),才会重启容器。 - unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
restart: "no" restart: always restart: on-failure restart: unless-stoppedsecrets
存储敏感数据,例如密码:
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
stop_signal
设置停止容器的替代信号。默认情况下使用 SIGTERM 。
以下示例,使用 SIGUSR1 替代信号 SIGTERM 来停止容器。
stop_signal: SIGUSR1
- sysctls
- 设置容器中的内核参数,可以使用数组或字典格式。
sysctls: net.core.somaxconn: 1024 net.ipv4.tcp_syncookies: 0 sysctls: - net.core.somaxconn=1024 - net.ipv4.tcp_syncookies=0volumes
将主机的数据卷或着文件挂载到容器里。
version: "3.7"
services:
db:
image: postgres:latest
volumes:
- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
- "/localhost/data:/var/lib/postgresql/data"



