
Docker Compose配置文件详解
Compose配置文件结构
version: "3.8"
services:
redis:
image: redis:alpine
ports:
- "6379"
networks:
- frontend
deploy:
replicas: 2
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
db:
image: postgres:9.4
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
deploy:
placement:
constraints:
- "node.role==manager"
vote:
image: dockersamples/examplevotingapp_vote:before
ports:
- "5000:80"
networks:
- frontend
depends_on:
- redis
deploy:
replicas: 2
update_config:
parallelism: 2
restart_policy:
condition: on-failure
result:
image: dockersamples/examplevotingapp_result:before
ports:
- "5001:80"
networks:
- backend
depends_on:
- db
deploy:
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
worker:
image: dockersamples/examplevotingapp_worker
networks:
- frontend
- backend
deploy:
mode: replicated
replicas: 1
labels: [APP=VOTING]
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 120s
placement:
constraints:
- "node.role==manager"
visualizer:
image: dockersamples/visualizer:stable
ports:
- "8080:8080"
stop_grace_period: 1m30s
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints:
- "node.role==manager"
networks:
frontend:
backend:
volumes:
db-data:
顶层的version、services、networks和volumes将Compose配置文件分为四个部分,其中version指定Compose配置文件的版本,services定义服务,networks定义网络,volumes定义数据卷。
服务配置
服务定义了该服务启动的每个容器的配置,就像将命令行参数传递给 docker run 一样。比如以下配置:
services:
redis:
image: redis
services 下的 redis 是用户自定义的服务名称,redis 下的 image 只是众多服务配置项中的其中一个,意思是指定镜像名称或 id。下面就对服务的相关配置项进行一个总结。
1. build
在构建时应用的配置项。一般直接指定 Dockerfile 所在文件夹路径,可以是绝对路径,或者相对于 Compose 配置文件的路径。可以指定为包含构建上下文(context)路径的字符串。例如:
version: "3.8"
services:
webapp:
build: ./dir
也可以使用 context 指定上下文路径,使用 dockerfile 基于上下文路径指定 Dockerfile 文件,使用 args 指定构建参数。例如:
version: "3.8"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
如果同时指定了 build 和 image。例如:
build: ./dir
image: webapp:tag
Compose 会在./dir 目录下构建一个名为 webapp,标签为 tag 的镜像。
使用 docker stack deploy 时的注意事项:在 swarm mode 下部署堆栈时,build 配置项被忽略。因为 docker stack 命令不会在部署之前构建镜像。
(1)context
指定包含 Dockerfile 的目录路径或 git 仓库 url。该目录是发送给 Docker 守护进程(Daemon)的构建上下文(context)。当配置的值是相对路径时,它将被解释为相对于 Compose 配置文件的路径。例如:
build:
context: ./dir
指定上下文为 Compose 配置文件目录下的 dir 目录。也可以这样写:
build: dir
(2)dockerfile
指定 Dockerfile 文件。Compose 会使用指定的 Dockerfile 文件构建镜像,但必须要指定构建上下文路径。例如:
build:
context: .
dockerfile: Dockerfile-alternate
Compose 会使用 Compose 配置文件所在目录下名为 Dockerfile-alternate 的 Dockerfile 文件构建镜像。
(3)args
添加构建参数,这些只能在构建过程中访问的环境变量。首先在 Dockerfile 文件中指定参数:
ARG buildno
ARG gitcommithash
RUN echo "Build number: $buildno"
RUN echo "Based on commit: $gitcommithash"
然后 build 中指定参数,以下两种写法都可以:
build:
context: .
args:
buildno: 1
gitcommithash: cdc3b19
build:
context: .
args:
- buildno=1
- gitcommithash=cdc3b19
这时构建过程中使用的参数的值为 args 指定的值。在指定构建参数时也可以不指定值,在这种情况下,构建过程中使用的参数的值为运行 Compose 的环境中的值。例如:
args:
- buildno
- gitcommithash
使用布尔值时的注意事项:YMAL 中布尔类型的值(“true”、“false”、“yes”、“no”、“on”、“off”)必须用引号引起来,以便解析器将它们解释为字符串。
(4)cache_from
在 3.2 版的配置文件格式中加入
指定缓存解析镜像列表。例如:
build:
context: .
cache_from:
- alpine:latest
- corp/web_app:3.14
(5)labels
在 3.3 版的配置文件格式中加入
将元数据以标签的形式添加到生成的镜像中。可以使用数组或字典两种格式。推荐使用反向 DNS 写法以避免和其他应用的标签冲突。例如:
build:
context: .
labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
build:
context: .
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
(6)network
在 3.4 版的配置文件格式中加入
设置容器网络连接以获取构建过程中的 RUN 指令。例如:
build:
context: .
network: custom_network_1
设置为 none 可以在构建期间禁用网络连接。例如:
build:
context: .
network: none
(7)shm_size
在 3.5 版的配置文件格式中加入
指定容器的 /dev/shm 分区大小。指定的值为表示字节数的整数值或表示字节值的字符串。例如:
build:
context: .
shm_size: 10000000
build:
context: .
shm_size: '2gb'
(8)target
在 3.4 版的配置文件格式中加入
指定在 Dockerfile 中定义的构建阶段,即镜像只构建到指定阶段就停止构建。例如:
build:
context: .
target: prod
指定构建阶段为 prod,即镜像只构建到 prod 阶段,prod 阶段之后的内容不会被构建。
2.cap_add、cap_drop
添加或删除容器内核能力(capability)。完整的 capability 列表可查看 man 7 capabilities。例如,让容器拥有所有内核能力:
cap_add:
- ALL
例如,删除 NET_ADMIN 和 SYS_ADMIN 能力:
cap_drop:
- NET_ADMIN
- SYS_ADMIN
使用 docker stack deploy 时的注意事项:在 swarm mode 下部署堆栈时,cap_add 和 cap_drop 配置项将被忽略。
3.cgroup_parent
为容器指定一个可选的父控制组。例如:
cgroup_parent: m-executor-abcd
使用 docker stack deploy 时的注意事项:在 swarm mode 下部署堆栈时,cgroup_parent 配置项将被忽略。
4.command
覆盖容器启动后默认执行的命令。可以写成字符串形式。例如:
command: bundle exec thin -p 3000
也可以写成 JSON 数组形式。例如:
command: ["bundle", "exec", "thin", "-p", "3000"]
5.configs
在 3.3 版的配置文件格式中加入
为每个服务授予对配置(configs)的访问权限。支持 short 和 long 两种格式的语法。更多 configs 信息,参考 configs。
注意:该配置(config)必须已存在或者在堆栈文件顶层 configs 配置项中定义,否则堆栈部署将失败。
short 语法仅指定 config 名称来授予容器访问 config 的权限并将其挂载到容器的 /<config_name> 上。source 名称和目标挂载点都设置为 config 名称。例如以下示例,授予了 redis 服务对 configs 的 my_config 和 my_other_config 的访问权限,其中 my_config 的值设置到文件./my_config.txt 的内容中,my_other_config 定义为外部资源,这意味着它已经在 Docker 中通过运行 docker config create 命令或其他堆栈部署进行定义,如果外部 config 不存在,堆栈部署将会失败并显示 config not found 错误:
version: "3.8"
services:
redis:
image: redis:latest
deploy:
replicas: 1
configs:
- my_config
- my_other_config
configs:
my_config:
file: ./my_config.txt
my_other_config:
external: true
long 语法提供了在服务的任务容器内如何创建 config 的更多粒度:
source:Docker 中存在的 config 名称。
target:指定要挂载到服务的任务容器的文件的路径加名称。如果未指定,默认为 /。
uid 和 gid:指定服务的任务容器所拥有的该文件的 UID 或 GID。如果在 LInux 中未指定,两者都默认为 0。不支持 Windows。
mode:以八进制表示法指定要挂载到服务的任务容器的文件权限。例如,0444 代表可读。默认值就为 0444。config 内容已挂载到临时文件系统中,所以不可写,如果设置了可写位将被忽略。可以设置可执行位。如果不熟悉 UNIX 文件权限模式,可以使用权限计算器 。
例如以下示例,指定 config 名称为 my_config,授予 redis 服务对 my_config 的访问权限,指定要挂载到 redis 服务的任务容器的路径加文件名称为 /redis_config,指定 UID 和 GID 均为 103,指定要挂载到服务的任务容器的文件权限为 0440(group-readable),但该 redis 服务没有访问 my_other_config 的权限:
version: "3.8"
services:
redis:
image: redis:latest
deploy:
replicas: 1
configs:
- source: my_config
target: /redis_config
uid: '103'
gid: '103'
mode: 0440
configs:
my_config:
file: ./my_config.txt
my_other_config:
external: true
可以授予服务访问多个 config 的权限,并且可以混合 long 和 short 语法。定义 config 并不意味着授予服务对其的访问权限。
6.container_name
指定自定义容器的名称,而不是使用默认名称。例如:
container_name: my-web-container
因为 Docker 容器的名称必须唯一,所以为一个服务指定了自定义容器名称后,该服务不能进行扩展。如果尝试为该服务扩容将会导致错误。
使用 docker stack deploy 时的注意事项:在 swarm mode 下部署堆栈时,container_name 配置项将被忽略。
7.credential_spec
在 3.3 版的配置文件格式中加入 在 3.8 或更高版本文件格式中支持将组托管服务帐户(GMSA)配置与 Compose 配置文件一起使用。
配置托管服务帐户的凭据规格(credential spec)。此选项仅用于使用 Windows 容器的服务。credential_spec 配置必须采用 file:// 或 registry:// 格式。使用 file: 时,引用的文件必须存在于 Docker 数据目录的 CredentialSpecs 子目录中,在 Windows 上,Docker 数据目录默认为 C:\ProgramData\Docker\。以下示例从名为 C:\ProgramData\Docker\CredentialSpecs\my-credential-spec.json 的文件加载凭证规格:
credential_spec:
file: my-credential-spec.json
使用 registry: 时,将从守护进程主机上的 Windows 注册表中读取凭据规格。其注册表值必须位于 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs。以下示例从注册表中名为 my-credential-spec 的值加载凭证规格:
credential_spec:
registry: my-credential-spec
为服务配置 GMSA 凭据规格时,只需用 config 指定凭据规格。例如:
version: "3.8"
services:
myservice:
image: myimage:latest
credential_spec:
config: my_credential_spec
configs:
my_credentials_spec:
file: ./my-credential-spec.json
8.depends_on
指定服务之间的依赖关系,解决服务启动先后顺序问题。指定服务之间的依赖关系,将会导致以下行为:
docker-compose up 以依赖顺序启动服务。
docker-compose up SERVICE 会自动包含 SERVICE 的依赖项。
docker-compose stop 以依赖顺序停止服务。
例如以下示例:
version: "3.8"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
启动时会先启动 db 和 redis,最后才启动 web。在使用 docker-compose up web 启动 web 时,也会启动 db 和 redis,因为在 web 服务中指定了依赖关系。在停止时也在 web 之前先停止 db 和 redis。
使用 depends_on 时的注意事项:
服务不会等待该服务所依赖的服务完全启动之后才启动。例如上例,web 不会等到 db 和 redis 完全启动之后才启动。
V3 版不再支持的 condition 形式的 depends_on。
V3 版中,在 swarm mode 下部署堆栈时,depends_on 配置项将被忽略。
9.deploy
在 3 版的配置文件格式中加入
指定部署和运行服务的相关配置。该配置仅在 swarm mode 下生效,并只能通过 docker stack deploy 命令部署,docker-compose up 和 docker-compose run 命令将被忽略。例如:
version: "3.8"
services:
redis:
image: redis:alpine
deploy:
replicas: 6
placement:
max_replicas_per_node: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
deploy 配置项中包含 endpoint_mode、labels、mode、placement、replicas、resources、restart_policy、update_config 等子配置项。
(1)endpoint_mode
在 3.2 版的配置文件格式中加入
为外部客户端连接到 swarm 指定服务发现方式:
endpoint_mode: vip:Docker 为服务分配了一个前端的虚拟 IP,客户端通过该虚拟 IP 访问网络上的服务。Docker 在客户端和服务的可用工作节点之间进行路由请求,而无须关系有多少节点正在参与该服务或这些节点的 IP 地址或者端口。这是默认设置。
endpoint_mode: dnsrr:DNS 轮询(DNSRR),Docker 设置服务的 DNS 条目,以便对服务名称的 DNS 查询返回 IP 地址列表,并且客户端通过轮询的方式直接连接到其中之一。
例如:
version: "3.8"
services:
wordpress:
image: wordpress
ports:
- "8080:80"
deploy:
mode: replicated
replicas: 2
endpoint_mode: vip