关于 docker-compose 的安装,关于 docker 的基本介绍,不在本文的指导范围内。php
这篇文章基本上是 docker-compose YAML 文件格式的严格的英译中。这么作,缘起于昨天想起扫描一下 docker-compose 编排中怎么使用 ${PWD}
的问题,结果中文没有一点帮助,仍是官网最终解决了个人模糊之处。所以我以为仍是应该作一篇比较严谨的译文以及说明,来阐释 docker-compose 编排的各项细节。html
如下,咱们主要是介绍 docker-compose 编排文件格式版本3 的各项细节。node
阅读本文,你应该有 docker-compose 的基本认识,至少有基本的早期(版本2)编排格式的了解。mysql
译文从属于原文 docs.docker.com/compose/com…。linux
译文 https://github.com/hedzr/docker-compose-file-format 自己以 MIT 方式(忽略 hedzr.github.io 站台级许可申明,遵循 repo 自己的申明)分发。nginx
git
上一次我作了一个旧的译文:docker-compose 编排指南 (v3.7)。这是基于 v3.7 的。今次的译文是对其的一个更新。不得不说,这种查漏补缺挺烦人的。github
版本3是自 docker-engine 1.13 推出以来 docker-compose 所支持的格式。这以前 docker 在 1.12 中推出了 swarm mode 来构建一个虚拟网络中的虚拟计算资源,同时也大幅度改进了 docker 的网络以及存储的支持。golang
对于 docker-compose 编排格式与 docker-engine 之间的关系,下面这张表(摘自官网)有清晰的对照。web
Compose file format | Docker Engine release |
---|---|
3.8 | 19.03.0+ |
3.7 | 18.06.0+ |
3.6 | 18.02.0+ |
3.5 | 17.12.0+ |
3.4 | 17.09.0+ |
3.3 | 17.06.0+ |
3.2 | 17.04.0+ |
3.1 | 1.13.1+ |
3.0 | 1.13.0+ |
2.4 | 17.12.0+ |
2.3 | 17.06.0+ |
2.2 | 1.13.0+ |
2.1 | 1.12.0+ |
2.0 | 1.10.0+ |
1.0 | 1.9.1.+ |
这是一个版本3+的典型文件结构样本:
version: "3.7" # 适用于 v3.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
等等标签构成。这与版本2并无什么翻天覆地的区别。
在 services
章节中,你能够定义若干个服务,每一个服务一般运转着一个容器,这些服务构成了一个总体的设施栈,又或是服务群。
通常来讲咱们会把一堆拉拉杂杂的东西,例如一堆微服务什么的,编排成一个服务栈,让他们总体对外服务,从而避免细节外露,也能够增强架构设计弹性和对整个服务栈进行伸缩(而不是面对大批微服务去逐个处理)。
ENTRYPOINT
和 CMD
在 Dockerfile 中讨论这三条命令:
首先,RUN
不考虑,其用途能够被视做执行一条Shell指令。
CMD
和 ENTRYPOING
类似但实际上区别较大:CMD
指定默认命令及其命令行参数、或者命令行参数的结尾的部分,而且可以在启动容器时被覆盖(经过外部命令行指定的方式),ENTRYPOINT
指定该容器被运行时的启动命令,能够附带命令行参数,这条命令在被实际执行时还会附加 CMD
所指定的内容做为其命令行的结尾部分。
因此一个惯用法是:
ENTRYPOINT ["/bin/echo", "Hello"] CMD ["world"] 复制代码
而后执行该容器的效果相似于:
$ docker run -it test-container Hello world $ docker run -it test-container David Hello David 复制代码
因此对于自定义容器来讲,你的主要应用程序的路径能够被用做 ENTRYPOINT
而在 CMD
中提供默认参数:
ENTRYPOINT ["/usr/local/app/my-app"] CMD ["--help"] 复制代码
这将会包装你的 my-app 像一个外露的工具,默认时显示其帮助屏,你能够指定参数去运行 my-app:
$ docker run -it my-app-container [... help screen here ...] $ docker run -it my-app-container server run --foreground [ 等同于执行 my-app server run --foreground ] 复制代码
END
多遍构建被典型地用于CI/CD。
例如步骤0能够被命名为 builder
,负责从源码编译到目标文件,而步骤1则从步骤0中抽出目标文件用于部署打包,并生成最终的容器镜像,随后步骤0的中间层则被抛弃(仅指不被打包在结果容器中,实际上这些中间层在 Docker 的构建缓存中仍然是存在且能够被重用的),这些中间层不会出如今最终容器镜像中,从而有效地缩减了最终容器镜像的尺寸,而这个结果也是从语义上、从逻辑上被自洽的。
FROM golang:1.7.3 AS builder WORKDIR /go/src/github.com/alexellis/href-counter/ RUN go get -d -v golang.org/x/net/html COPY app.go . RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /go/src/github.com/alexellis/href-counter/app . CMD ["./app"] 复制代码
service
配置参考接下来会是一个参考手册应有的章节结构,咱们按照字母顺序列列举出了服务编排的指令,例如
ports
,volumes
,cmd
,entry
等等。
Compose 文件是一个 YAML格式的文本文件,其中定义了 service、networks 以及 volumes。缺省时 docker-compose 使用和检索 ./docker-compose.yml
文件并解释之。
Tip: 你老是可使用
.yml
或.yaml
做为该脚本文件的后缀,它们都会正确工做。
service (服务)的配置包含若干定义,它们指明了如何将一个容器运行为服务,这些定义实际上会被传递给 docker run
做为其命令行参数的一部分。一样的道理,networks、volumes 等等的定义也采用一样的原理去影响诸如 docker network create
,或者 docker volume create
等命令的实际运行。
你可使用在配置定义值中使用环境变量,它们有相似于 BASH 变量替代的语法,你能够以 ${VARIABLE}
,请参阅 变量替换 小节的深刻探讨。
接下来本章节中列举全部有效的服务配置项。
build
该选项被用于构建。
build
能够是一个指向构建上下文的路径字符串,例如:
version: "3.8" services: webapp: build: ./dir 复制代码
也能够是一个更详细的定义。这包括了 context
项所指定的路径,以及可选的 dockerfile
文件和构建参数 args
:
version: "3.8" services: webapp: build: context: ./dir dockerfile: Dockerfile-alternate args: buildno: 1 复制代码
若是你在指定了 build
的同时还指定了 image
,那么构建的结果会被标记为相应的名字,这就好像 docker build -t container-name:tag dir
作的那样:
build: "./dir" image: "company/webapp:v1.1.9" 复制代码
对于 YAML 而言,避免歧义的安全作法是对字符串加上引号包围。
上面这个例子,会找到 ./dir
文件夹中的构建上下文(默认是寻找到 Dockerfile
)并完成构建,最后将其标记为 company/webapp
的名字,以及 v1.1.9
的 Tag。
NOTE 当用在docker stack部署场景时:
build
选项会被忽略。
context
能够是一个包含 Dockerfile
的文件夹,也能够是一个指向 git repository 的 URL。
若是指定了一个相对路径,那么这个路径是相对于 docker-compose.yml
文件的。这个路径也会被传送给 Docker daemon 用于进行构建。
docker-compose 发动构建动做和标记构建结果(按照image
名字),在那以后按照对应的名字使用它。
build: context: ./dir 复制代码
dockerfile
能够指定不一样于默认名称 Dockerfile
的其它文件名用于构建。注意同时必须指定路径到 context
:
build: context: . dockerfile: Dockerfile-alternate 复制代码
args
指定构建参数。一般是指用于构建时的参数(参见 Dockerfile 中的 ARG
)。
如下是一个简要的概述:
首先,在 Dockerfile 指定参数:
ARG buildno ARG gitcommithash RUN echo "Build number: $buildno" RUN echo "Based on commit: $gitcommithash" 复制代码
而后指定构建参数的实际值(传入Map或者数组都是能够的):
build: context: . args: buildno: 1 gitcommithash: cdc3b19 复制代码
或:
build: context: . args: - buildno=1 - gitcommithash=cdc3b19 复制代码
NOTE: 在 Dockerfile中,若是在
FROM
以前指定ARG
,那么这个ARG
对于其后的FROM
闭包是无效的。多个
FROM
分别切割出了多个构建的闭包。想要
ARG
在每一个FROM
闭包中都有效,你须要在每一个闭包中都指定它。在 Understand how ARGS and FROM interact 中有更详细的相关讨论。
你能够略过显式指定构建参数。此时,该参数的实际值取决于构建时运行环境。
args: - buildno - gitcommithash 复制代码
NOTE: YAML的布尔量(
true
,false
,yes
,no
,on
,off
)必须用引号包围,以便 docker-compose正确处理。
cache_from
since v3.2
指定一个映像列表,用于缓存的解决。
build: context: . cache_from: - alpine:latest - corp/web_app:3.14 复制代码
labels
since v3.3
向构建的映像中添加元数据标签,能够是一个数组或一个字典。
咱们推荐使用反向DNS标注性前缀以防止你的标签和使用者的标签相冲突:
build: context: . labels: com.example.description: "Accounting webapp" com.example.department: "Finance" com.example.label-with-empty-value: "" # anothor example build: context: . labels: - "com.example.description=Accounting webapp" - "com.example.department=Finance" - "com.example.label-with-empty-value" 复制代码
network
Since v3.4
设置在 RUN
构建过程当中要连接的网络,该网络也将被用于查询和提取依赖的容器。
build: context: . network: host build: context: . network: custom_network_1 复制代码
设为 none
则在构建时禁用网络查询和提取:
build: context: . network: none 复制代码
shm_size
since v3.5
设置构建容器时的 /dev/shm
分区大小。整数格式按字节表示,但也可使用字符串格式(byte value):
build: context: . shm_size: '2gb' build: context: . shm_size: 10000000 复制代码
target
since v3.4
构建定义与 Dockerfile 中的特定的步骤(Stage),参阅 multi-stage build docs:
build: context: . target: prod 复制代码
cap_add
, cap_drop
添加或者移除容器的 Linux 能力。完整的清单能够参阅 man 7 capabilities
。
cap_add: - ALL cap_drop: - NET_ADMIN - SYS_ADMIN 复制代码
NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。
Linux 能力机制很大程度上是一种安全机制。具体含义、用途和引伸属于 Linux 操做系统范畴,再也不赘述。
cgroup_parent
可选地为容器指定一个上级 cgroup
。cgroup
也是 Linux 容器化实现的最重要的基本概念之一。
cgroup_parent: m-executor-abcd 复制代码
NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。
command
覆盖容器内默认的 command
.
command: bundle exec thin -p 3000 复制代码
command
也能够被指定为一个列表。实际上这也是更被推荐的方式,无歧义并且安全,并且和 dockerfile 中的格式具备一致性:
command: ["bundle", "exec", "thin", "-p", "3000"] 复制代码
为每一个服务提供具体化的访问 config
的权限。
一个 config
包含一系列的配置信息,这些信息可能被经过多种途径所建立。容器的部署引用这些配置时,能够更好地区格诸如生产环境参数这样的问题。另外一方面,敏感信息也所以能够被单独隔离到一个安全的区域中,在必定程度上减小了泄露的可能性。
NOTE: 指定的配置必须已经存在,或者已经被定义在顶级
configs
中了(defined in the top-levelconfigs
configuration)。不然整个容器栈的部署将会失败。
支持两个不一样的语法变体格式。更详尽的信息应参考 configs。
只指定配置名。容器所以能够访问配置 /<config_name
和挂载它(挂载的源和目标均为该配置名)。
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 复制代码
上面的例子使用短格式在 redis
容器的服务中定义了 my_config
和 my_other_config
的引用。这里的 my_config
指定为一个宿主机文件 ./my_config.txt
,而 my_other_config
被指定为外部的(资源),这意味着相应的资源已经在 Docker 中被定义了,或许是经过 docker config create
创建的,又或者是被别的容器栈部署所创建的。
若是外部资源找不到,那么容器栈的部署将会失败,而且抛出一个 config not found
的错误。
Note:
config
定义仅在 v3.3 及更高版本的 docker-compose 格式中被支持。
长格式提供更多的信息来表述一个 config
在哪儿,如何被找到,怎么被使用:
source
: 配置名
target
: 该配置将被挂载到容器中的路径。默认为 /<source>
uid
& gid
: 数字值的 Linux/Unix UID
和 GID
,若是没有指定则为0。Windows中不支持。
mode
: 8进制的文件权限。默认值为 0444
。
配置是不可写的,由于它们被挂载于临时的文件系统中。所以若是你设置了写许可,这将被忽略。
可执行位是能够被设置的。
下面的例子相似于短格式的例子:
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 复制代码
在这里,redis
容器的服务并未访问 my_other_config
。
你能够受权一个服务访问多个配置,你也能够混用长短格式。
(在顶级)定义一个配置(config
)并未隐含着某个服务就能访问到它。
container_name
指定一个自定义的容器名,而不是由 docker-compose 本身生成一个默认的。
container_name: my-web-container 复制代码
因为 Docker 容器名必须是惟一的,因此你没法伸缩一个自定义了容器名的服务。
NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。
credential_spec
since v3.3
从 v3.8 开始支持被用于组管理服务帐户 gMSA(group Managed Service Account)方式。
为受控服务帐户配置凭据。这个选项只被用于 Windows 容器服务。credential_spce
只能使用格式 file://<filename>
or registry://<value-name>
。
当使用 file:
时,被参考的文件必须被置于 Docker 数据文件夹(一般是 C:\ProgramData\Docker\
)的 CredentialSpec
子目录之下。下面的例子将会从 C:\ProgramData\Docker\CredentialSpecs\my-credential-sp
载入凭据信息:
credential_spec: file: my-credential-spec.json 复制代码
当使用 registry:
时,凭据信息将会被从 Docker daemon 主机的 Windows Registry 中读入。一个注册表表项必须位于:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs
复制代码
之中。
下面的例子读入 my-credential-spec
注册表项值:
credential_spec: registry: my-credential-spec 复制代码
当为一个服务配置 gMSA 凭据时,参考以下的例子:
version: "3.8" services: myservice: image: myimage:latest credential_spec: config: my_credential_spec configs: my_credentials_spec: file: ./my-credential-spec.json| 复制代码
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.8" services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres 复制代码
使用
depends_on
时应该注意的几件事:
depends_on
并不意味着等待db
和redis
就绪后才启动web
,而是在它们被启动后就会接着启动web
。若是要想等到服务就绪可用,应该参阅 Controlling startup order。版本 3 再也不支持
condition
表述。
depends_on
选项在部署到 swarm mode 时被忽略。
deploy
Version 3 only.
指定和部署以及运行相关的配置。
只会对部署到一个使用 docker stack deploy 的 swarm 有影响。
在 docker-compose up
和 docker-compose run
时被忽略。
version: "3.8" services: redis: image: redis:alpine deploy: replicas: 6 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure 复制代码
几个子选项是可用的:
endpoint_mode
swarm.
Since Version 3.2.
指定外部客户端链接到一个 swarm 集群时使用的服务发现方法。
endpoint_mode: vip
- Docker 为服务请求一个虚拟IP(VIP
)用于访问。
Docker在客户端和服务的有效的工做节点之间对请求进行自动负载均衡路由。客户端无需知道服务有多少可用节点,也没必要知道服务节点的IP地址和端口号。
这是默认方式。
endpoint_mode: dnsrr
- 使用 DNS round-robin (DNSRR) 算法进行服务发现。Docker会为服务设置一个DNS条目,于是在进行对应的 DNS 解析时经过服务名称会返回一个IP地址清单。客户端所以直接选择一个具体的端点进行访问。
version: "3.8" services: wordpress: image: wordpress ports: - "8080:80" networks: - overlay deploy: mode: replicated replicas: 2 endpoint_mode: vip mysql: image: mysql volumes: - db-data:/var/lib/mysql/data networks: - overlay deploy: mode: replicated replicas: 2 endpoint_mode: dnsrr volumes: db-data: networks: overlay: 复制代码
endpoint_mode
的选项也被一样地用做 swarm mode 命令行选项(参阅 docker service create
)。至于 docker swarm命令的一个快捷清单,能够查阅 Swarm mode CLI commands。
要学习更多关于 swarm mode 的网络模型已经服务发现机制 的知识,请查看 Configure service discovery。
labels
为服务指定标签。这些标签只被做用于对应的服务,而不是被应用到服务的容器或者容器实例上。
version: "3.8" services: web: image: web deploy: labels: com.example.description: "This label will appear on the web service" 复制代码
要为容器设置标签的话,在 deploy
以外为服务指定 labels
:
version: "3.8" services: web: image: web labels: com.example.description: "This label will appear on all containers for the web service" 复制代码
mode
能够是 global
或 replicated
。global
表示严格地一个 swarm node 跑一个服务,replicated
表示能够跑多个容器实例。默认是 replicated
。
参阅 swarm 主题下的 Replicated and global services。
version: "3.8" services: worker: image: dockersamples/examplevotingapp_worker deploy: mode: global 复制代码
placement
指定 constaints 和 preferences。
参阅docker服务创建的相关文档以了解更多的关于 constraints 和 [preferences 的相关信息,包括相应的语法,可用的类型等等的完整描述。
version: "3.8" services: db: image: postgres deploy: placement: constraints: - node.role == manager - engine.labels.operatingsystem == ubuntu 14.04 preferences: - spread: node.labels.zone 复制代码
max_replicas_per_node
Since version 3.8.
若是一个服务是可副本的 replicated
(这是默认的), max_replicas_per_node 将会 限制副本数量(limit the number of replicas) 。
当太多任务申请新的任务节点且超出了 max_replicas_per_node 限制值时,一个 no suitable node (max replicas per node limit exceed)
错误将会被抛出。
version: "3.8" services: worker: image: dockersamples/examplevotingapp_worker networks: - frontend - backend deploy: mode: replicated replicas: 6 placement: max_replicas_per_node: 1 复制代码
replicas
若是服务是 replicated
的,replicas
则为其指定一个数值,此数值指示了一个 swarm 节点上最多能够跑多少个容器实例。
version: "3.7" services: worker: image: dockersamples/examplevotingapp_worker networks: - frontend - backend deploy: mode: replicated replicas: 6 复制代码
resources
配置资源约束。
NOTE: 对于非 swarm mode 而言,这个表项替换 older resource constraint options(诸如
cpu_shares
,cpu_quota
,cpuset
,mem_limit
,memswap_limit
,mem_swappiness
等在版本3以前版本中的表项)。在 Upgrading version 2.x to 3.x 中有相应的描述。
这些资源约束表项都具备一个单一值,至关于 docker service create
中的等价物。
在以下的例子中,redis
服务被约束为不可以使用超出50M的内存,单核50%的CPU使用率,同时也保留 20M 内存以及 25%的CPU使用率做为基准值。
version: "3.8" services: redis: image: redis:alpine deploy: resources: limits: cpus: '0.50' memory: 50M reservations: cpus: '0.25' memory: 20M 复制代码
如下的主题描述 swarm 场景下的服务或容器资源约束的可用选项。
企图在你的服务和容器实例中使用超过系统拥有的内存,那么将获得 Out Of Memory Exception (OOME) 。此时,容器实例,或者 Docker daemon,可能会被内核的 OOM 管理器所清除。
要防止这样的状况发生,请肯定你的应用程序合法有效地使用内存。对于这样的风险,查阅 Understand the risks of running out of memory 以获知进一步的评估须知。
restart_policy
指示当容器实例退出时,如何重启。替换 restart
:
condition
: 能够为 none
, on-failure
或 any
(默认为 any
)delay
: 在尝试重启以前的等候时长(默认为0)。应该为其指定一个 duration。max_attempts
: 试图尝试重启多少次后放弃重启的尝试。默认为不放弃。window
: 要肯定一次重启是否成功,须要等候的时长。默认为无等待当即认定为已成功。应该为其指定一个 duration。version: "3.8" services: redis: image: redis:alpine deploy: restart_policy: condition: on-failure delay: 5s max_attempts: 3 window: 120s 复制代码
rollback_config
Version 3.7 file format and up
在滚动更新失败的场景下服务应该如何回滚:
parallelism
:同时回滚的容器的数量值。若是设置为0,全部容器将被同时回滚。delay
: 每一个容器组被回滚前的等待时长(默认为0)failure_action
: 一个回滚失败时应当执行的动做。能够是 continue
或 pause
(默认为pause
)monitor
: 失败的回滚状态被更新到监视器的周期(ns|us|ms|s|m|h
)默认为 0s
。max_failure_ratio
: 回滚时失败的可容忍的比例(默认为0)order
: 回滚的操做顺序。能够为 stop-first
或 start-first
(默认为 stop-first
)update_config
指示服务应该如何被更新。这对于配置为滚动更新时有用:
parallelism
:同时更新的容器的数量值。若是设置为0,全部容器将被同时回滚。delay
: 每一个容器组被更新前的等待时长(默认为0)failure_action
: 一个更新失败时应当执行的动做。能够是 continue
, rollback
或 pause
(默认为pause
)monitor
: 失败的更新状态被更新到监视器的周期(ns|us|ms|s|m|h
)默认为 0s
。max_failure_ratio
: 更新时失败的可容忍的比例(默认为0)order
: 更新的操做顺序。能够为 stop-first
或 start-first
(默认为 stop-first
)NOTE:
order
只在 v3.4 及以后有效。
version: "3.8" services: vote: image: dockersamples/examplevotingapp_vote:before depends_on: - redis deploy: replicas: 2 update_config: parallelism: 2 delay: 10s order: stop-first 复制代码
DOCKER STACK DEPLOY
不支持者下列的子选项(为 docker-compose up
和 docker-compose run
所支持)是在 docker stack deploy
中不被支持的:
Tip: 请参阅 如何为 service 服务模式和 swarm 集群模式使用卷而配置 docker-stack.yml 文件 - how to configure volumes for services, swarms, and docker-stack.yml files 章节。 Volumes(卷)在 swarms 模式和 services 模式中是被支持的,但你只能采用命名卷,又或是与受约束于有权访问必需卷的节点的服务关联.
devices
要被映射的设备清单。其用法和 docker 命令的 --device
相同。
devices: - "/dev/ttyUSB0:/dev/ttyUSB0" 复制代码
NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。
dns
自定义 DNS 服务器列表。能够指定单一值或一个清单。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
复制代码
dns_search
自定义DNS搜索域名。能够指定单一值或一个清单。
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
复制代码
entrypoint
覆盖 dockerfile 中定义的默认的 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 复制代码
NOTE: 设置一个
entrypoint
不但覆盖 Dockerfile 中的任何ENTRYPOINT
默认值,还会清理 Dockerfile 中的任何CMD
默认值。因此 Dockerfile 中的CMD
将会被忽略。
env_file
从给定的文件中引入环境变量值。能够是单一值或一个清单。
env_file: .env env_file: - ./common.env - ./apps/web.env - /opt/secrets.env 复制代码
对于 docker-compose -f FILE
来讲,env_file
的路径是相对于 FILE
所在文件夹的。
在 environment
中声明的环境变量将会覆盖掉这里所引入的值。
对应的文件中,每一行应该使用 VAR=VAL
格式定义一个环境变量。行首为 #
表示为注释行,和空白行同样被忽略。
# Set Rails/Rack environment RACK_ENV=development 复制代码
NOTE: 若是服务定义了
build
项,在构建过程当中,由env_file
所定义的环境变量并不可见。只能使用build
的子选项args
去定义构建时环境变量值。
VAL
的值被原样照用,且不能被修改。例如若是值由引号所包围,那么值的表示量中也包含引号。
环境变量文件的顺序也须要被注意。位置靠后的环境变量文件中所定义的变量值会覆盖掉早前定义的旧值。
按:原文居然说了这么多!
Keep in mind that the order of files in the list is significant in determining the value assigned to a variable that shows up more than once. The files in the list are processed from the top down. For the same variable specified in file
a.env
and assigned a different value in fileb.env
, ifb.env
is listed below (after), then the value fromb.env
stands. For example, given the following declaration indocker-compose.yml
:
services:
some-service:
env_file:
- a.env
- b.env
复制代码
And the following files:
# a.env VAR=1 复制代码
and
# b.env VAR=hello 复制代码
$VAR
is hello
.
environment
添加环境变量。可使用一个数组或者一个字典。任何布尔量:true, false, yes, no 等等都必须用引号包围为字符串字面量。
只有key值的环境变量的value值依赖于 docker-compose 运行时的主机环境,这对于防止敏感信息泄露是有用的。
environment: RACK_ENV: development SHOW: 'true' SESSION_SECRET: # 或 environment: - RACK_ENV=development - SHOW=true - SESSION_SECRET 复制代码
NOTE: 若是服务定义了
build
项,在构建过程当中,由env_file
所定义的环境变量并不可见。只能使用build
的子选项args
去定义构建时环境变量值。
expose
暴露端口到连接的服务。这些端口并不会被发布到宿主机。只能指定内部端口被用于暴露。
expose: - "3000" - "8000" 复制代码
external_links
将在 docker-compose.yml
以外启动的容器连接到给定服务上。
和遗留选项 links
有类似的语义。
external_links: - redis_1 - project_db_1:mysql - project_db_1:postgresql 复制代码
Note
在 docker-compose.yml 以外创建的容器(The externally-created containers)必须至少链接到一个相同的网络,才能与一个定义在 docker-compose.yml 中的服务相连接 。Links 选项已通过时了,咱们推荐使用 networks 来代替它。
NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。
更推荐的作法是经过 networks
构造一个子网以进行容器之间的连接。
extra_hosts
添加主机名映射。这些映射关系会被添加到 /etc/hosts
中。此功能等价于命令行参数 --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 otherhost
复制代码
healthcheck
since v2.1
用于确认一个服务是不是“健康”的。参阅 HEALTHCHECK Dockerfile instruction。
healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] interval: 1m30s timeout: 10s retries: 3 start_period: 40s 复制代码
interval
, timeout
和 start_period
应该被指定为 durations.
Note:
start_period
只在 v3.4 及之后可用。
test
必须是一个单一字符串值或一个列表。若是是一个列表,那么第一项必须是 NONE
, CMD
, CMD-SHELL
之一。若是是一个字符串,隐含地表示一个 CMD-SHELL
前缀。
# Hit the local web app test: ["CMD", "curl", "-f", "http://localhost"] 复制代码
如上述示例,但隐含调用 /bin/sh
,和如下的形式是等效的。
test: ["CMD-SHELL", "curl -f http://localhost || exit 1"] test: curl -f https://localhost || exit 1 复制代码
要禁用任何在映像内指定的缺省的健康检查向,可使用 disable: true
。这和指定 test: ["NONE"]
是等效的。
healthcheck: disable: true 复制代码
image
指定映像的名称。
image: redis image: ubuntu:14.04 image: tutum/influxdb image: example-registry.com:4000/postgresql image: a4bc65fd 复制代码
若是映像在宿主机不存在,Compose 会尝试下拉它,除非你也指定了 build
项。
init
since v3.7
在容器中运行一个 init 进程并转发信号。设置为 true
为服务使能这个特性。
version: "3.8" services: web: image: alpine:latest init: true 复制代码
缺省的 init 进程使用二进制执行文件 Tini,在须要时它将被安装于 daemon主机的位置
/usr/libexec/docker-init
。你也能够配置 daemon 使用一个不一样的二进制文件,经过init-path
,参阅 configuration option。
isolation
指定一个容器的隔离层级/技术。在 Linux 中,仅支持 default
值。在 Windows 中,能够接受的值有:default
, process
和 hyperv
。
labels
为容器添加元数据标签,参考 Docker labels。能够为其指定一个数组或一个字典。
咱们建议你采用反向DNS标注方式来定义你的标签,这能够有效地避免标签名称的冲突。
labels: com.example.description: "Accounting webapp" com.example.department: "Finance" com.example.label-with-empty-value: "" labels: - "com.example.description=Accounting webapp" - "com.example.department=Finance" - "com.example.label-with-empty-value" 复制代码
links
已是一个遗留特征了。在不久的将来将被移除。
按:因此我也不精确翻译了:) 太啰嗦了。
连接另外一个服务到本容器。能够同时制定服务名称和连接别名(SERVICE:ALIAS
),也能够略过连接别名。
web: links: - db - db:database - redis 复制代码
已经被链入的服务将会是主机名(即连接别名 ALIAS
)可访问的。
对于服务间通信来讲,连接并非必须的。默认状况下,任何服务均可以经过服务名访问到其余服务。参阅 Links topic in Networking in Compose。
连接也表示一个依赖关系,但这已是 depends_on
的任务了,因此连接也并没必要要了。
logging
为服务指定日志转发配置。
logging: driver: syslog options: syslog-address: "tcp://192.168.0.42:123" 复制代码
driver
指定了驱动名称,这和 --log-driver
是等效的。
缺省值为 json-file
。
driver: "json-file" driver: "syslog" driver: "none" 复制代码
Note
使用
docker-compose up
和docker-compose logs
检索日志时,只有json-file
和journald
驱动格式的日志才能被打印到控制台,其余日志驱动程序会将日志转发到对应的目的地,本地将不会检索到任何日志输出信息。
可用的转发驱动器能够参考 docs.docker.com/config/cont…
使用 option
指定驱动器的选项,如同 --log-opt
那样。例如为 syslog
这样指定:
driver: "syslog" options: syslog-address: "tcp://192.168.0.42:123" 复制代码
缺省的日志转发驱动为 json-file
。对此能够指定日志切割尺寸以及最多保持的日志历史文件个数:
options: max-size: "200k" max-file: "10" 复制代码
上面显示的这个例子中,日志的文件存储将被限制为 200kB,而且在超出时会被截断到旧历史日志,这样的历史文件将被限制为不超过 10 个,更旧的历史文件将被抛弃。
这里有一个完整的 docker-compose.yml
文件实例,演示了如何限制日志存储空间:
version: "3.8" services: some-service: image: some-service logging: driver: "json-file" options: max-size: "200k" max-file: "10" 复制代码
有效可用的日志选项有赖于具体使用的日志驱动程序。
上面的控制日志文件个数及其大小的日志选项,适用于 json-file driver。它们可能并不适用于别的日志驱动程序。要了解完整的针对每一个日志驱动程序可用的日志选项,请查阅 logging drivers 文档。
network_mode
网络模型。
和 --network
的取值相同。但额外支持 service:[service name]
模式。
network_mode: "bridge" network_mode: "host" network_mode: "none" network_mode: "service:[service name]" network_mode: "container:[container name/id]" 复制代码
NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。
NOTE:
network_mode: "host"
不能和 links 混用。
networks
要加入的网络。目标网络是在 docker-compose.yml
顶级的 networks
项中定义的。
services: some-service: networks: - some-network - other-network 复制代码
指定网络中该服务的别名(也即主机名)。相同网络中别的容器可使用服务名或者服务别名来链接到该服务的容器实例。
既然 aliases
是网络范围(网络域)内的,同一个服务在不一样网络中能够有不一样的别名。
Note
一个网络域别名,能够被多个容器、甚至是多个服务所共享——你能够在不一样容器、不一样服务之间使用重名的别名。若是你这么作了,别名会被解决为哪一个肯定的容器是没法保证的。
别名定义的格式如同这样:
services: some-service: networks: some-network: aliases: - alias1 - alias3 other-network: aliases: - alias2 复制代码
一个更复杂而完整的例子:下面提供了三个服务:``web,
worker, 和
db,分别属于两个网络:
new和
legacy。经过
new网络中的主机名
db或
database来访问,或者
legacy网络的主机名
db或
mysql,均可以访问到
db` 服务。
version: "3.8" services: web: image: "nginx:alpine" networks: - new worker: image: "my-worker-image:latest" networks: - legacy db: image: mysql networks: new: aliases: - database legacy: aliases: - mysql networks: new: legacy: 复制代码
指定一个静态IP地址。
注意相应的顶级网络配置中,必须有 ipam
块对子网进行了配置且静态IP地址符合该子网定义。
If IPv6 addressing is desired, the
enable_ipv6
option must be set, and you must use a version 2.x Compose file. IPv6 options do not currently work in swarm mode.
一个例子是:
version: "3.8" services: app: image: nginx:alpine networks: app_net: ipv4_address: 172.16.238.10 ipv6_address: 2001:3984:3989::10 networks: app_net: ipam: driver: default config: - subnet: "172.16.238.0/24" - subnet: "2001:3984:3989::/64" 复制代码
pid
pid: "host" 复制代码
设置服务使用主机的 PID 模式。这使得容器内的服务进程和宿主机操做系统级可以共享 PID 地址空间。这是一个典型的 Linux/Unix 操做系统概念,所以这里再也不展开叙述了。这样的共享的做用,可使能安全的、借助PID地址空间的 IPC 通信。
ports
暴露端口到宿主机。
Note: 端口暴露功能和
network_mode: host
不能兼容。
能够同时指定宿主机和容器端口 (HOST:CONTAINER
) 以完成映射,也能够仅指定容器端口以自动映射为相同的主机端口一个临时端口(从32768开始)。
Note
当采用
HOST:CONTAINER
格式来映射端口时,若是使用的容器端口小于60的话,你可能会接受到一个错误。这是由于 YAML 解析器将格式xx:yy
视为一个 60 进制的数值。这挺荒谬的,是否是?因为这个缘由,咱们不得不推荐你在端口号这里老是使用引号作包围,令其成为一个 string 值,以避免收到不如预期的反应。
ports: - "3000" - "3000-3005" - "8000:8000" - "9090-9091:8080-8081" - "49100:22" - "127.0.0.1:8001:8001" - "127.0.0.1:5000-5010:5000-5010" - "6060:6060/udp" 复制代码
容许进行冗长的定义:
target
: 指定容器内的端口号published
: 指定暴露给 docker 宿主机的端口号protocol
: 协议 (tcp
or udp
)mode
: host
表示每一个节点的端口号都发布为宿主机端口,ingress
专用于 swarm 集群,全部节点的端口会被负载均衡为宿主机端口。ports: - target: 80 published: 8080 protocol: tcp mode: host 复制代码
意义明显,因此略过解说。
NOTE:长格式仅在 v3.2 及以后有效。
restart
no
是默认的重启策略。此时不管容器怎么退出、怎么失败也不会被自动重启。
指定 always
时任何状况下容器都会被重启。
on-failure
策略可在容器失败退出时才重启。
restart: "no" restart: always restart: on-failure restart: unless-stopped 复制代码
NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。(此时可使用
restart_policy
达到目的)
secrets
从每一个服务配置中,受权访问顶级 secrets
定义的表项。支持长短两个格式。
短格式仅指定敏感内容的名字。这使得容器可以挂载对应内容到 /run/secrets/<secret_name>
位置并访问它。
下面的例子使用短格式,让 redis
可以访问 my_secret
和 my_other_secret
。my_secret
的具体内容被定义在 ./my_secret.txt
,my_other_secret
被定义为外部资源,例如经过 docker secret create
方式预先定义。若是找不到对应的外部资源,stack部署将会失败并抛出一个 secret not found
错误。
version: "3.8" services: redis: image: redis:latest deploy: replicas: 1 secrets: - my_secret - my_other_secret secrets: my_secret: file: ./my_secret.txt my_other_secret: external: true 复制代码
长格式能够更精细地定义敏感内容如何被用于 stack 内容器。
source
: 敏感内容在 Docker 中所被定义的名字。target
: 被挂载到容器内 /run/secrets/
中的文件名。若是没指定则使用 source
名。uid
& gid
: 容器内挂载的文件的 UID 和 GID。如未指定则为0。在 Windows 中无效。mode
: 容器内挂载的文件的八进制许可权限。在 Docker 1.13.1 中默认值为 0000
,但在更新的版本中为 0444
。挂载的文件是不可写的。执行位能够被设置,但通常状况下没有意义。下面是一个例子:
version: "3.8" services: redis: image: redis:latest deploy: replicas: 1 secrets: - source: my_secret target: redis_secret uid: '103' gid: '103' mode: 0440 secrets: my_secret: file: ./my_secret.txt my_other_secret: external: true 复制代码
长短格式时能够被混用的,若是你在定义多个敏感内容。
security_opt
为每一个容器覆盖掉默认的标签语义。
security_opt: - label:user:USER - label:role:ROLE 复制代码
一般这和 seccomp 有关,这会是与安全配置有关的一个冗长的话题,故而此处不作展开。
NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。
指定一个等待时长,若是容器未能拦住 SIGTERM
信号(或者经过 stop_signal
定义的别的信号)正常地关闭本身,则在此时长以后强制清除容器实例的相应进程(经过 SIGKILL
信号)。
stop_grace_period: 1s stop_grace_period: 1m30s 复制代码
默认时,将会等候 10s 。
stop_signal
设置一个替代信号以正常关闭容器实例。默认时使用 SIGTERM
信号.
stop_signal: SIGUSR1 复制代码
sysctls
为容器设定内核参数。可使用一个数组或字典。
sysctls: net.core.somaxconn: 1024 net.ipv4.tcp_syncookies: 0 sysctls: - net.core.somaxconn=1024 - net.ipv4.tcp_syncookies=0 复制代码
NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。
tmpfs
v2 的解说在 v3.8 的原文里已经被删除了:
since v2
挂载一个临时文件系统到容器中。能够是一个单一值或一个列表。
tmpfs: /run tmpfs: - /run - /tmp 复制代码NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。
since v3.6
挂载一个临时文件系统到容器中。可使用一个单一值或一个数组。
tmpfs: /run tmpfs: - /run - /tmp 复制代码
NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。
挂载一个临时文件系统到容器中。Size参数能够指定文件系统尺寸的字节大小。默认值为无限。
- type: tmpfs target: /app tmpfs: size: 1000 复制代码
ulimits
覆盖容器内指定的默认的 ulimits 值。能够指定一个整数做为单一的 limit 限制,或者指定一个 mapping 以分别表示 soft/hard limit 限制。
ulimits: nproc: 65535 nofile: soft: 20000 hard: 40000 复制代码
userns_mode
userns_mode: "host" 复制代码
禁用用户名字空间。若是 Docker daemon 被配置运行在一个 user namespace 之中的话。
NOTE: 这些选项在部署一个栈到 swarm mode 时被忽略。
volumes
挂载宿主机路径或者命名卷。
能够挂载一个主机路径到一个服务中,此时无需在顶级 volumes
中对其进行定义。
若是想要重用一个卷到多个服务,那么应该在顶级 volumes
中定义它并命名它。
能够在 services, swarms, and stack files 中使用命名卷。
NOTE: 在顶级
volumes
中定义一个命名卷,并在一个服务的volumes
列表中引用它。早期的
volumes_from
再也不使用了。能够参阅 Use volumes and Volume Plugins。
下面的例子示意了一个命名卷 my_data
,且被用于 web
服务。在 web
中也使用一个主机文件夹 ./static
到容器内的挂载;在 db
中挂载了一个主机文件到容器内的对应文件,并使用了另外一个命名卷 dbdata
。
version: "3.8" services: web: image: nginx:alpine volumes: - type: volume source: mydata target: /data volume: nocopy: true - type: bind source: ./static target: /opt/app/static db: image: postgres:latest volumes: - "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock" - "dbdata:/var/lib/postgresql/data" volumes: mydata: dbdata: 复制代码
Note
关于卷的更多信息,请参阅 use volumes 和 volume plugins 章节。
可使用 HOST:CONTAINER
格式,或者附带一个访问模式 HOST:CONTAINER:ro
。
短格式的语法为 [SOURCE:]TARGET[:MODE]
。SOURCE
能够是一个主机路径,也能够是一个卷名。TARGET
是一个容器内路径 T,主机路径将被挂载到该路径 T。MODE
能够是 ro
或者 rw
,分别表明着 只读 和 可读写。
能够挂载一个主机中的相对路径,此路径是相对于 docker compose 文件而被展开的。相对路径应该老是以 .
或者 ..
开始。
volumes: # Just specify a path and let the Engine create a volume - /var/lib/mysql # Specify an absolute path mapping - /opt/data:/var/lib/mysql # Path on the host, relative to the Compose file - ./cache:/tmp/cache # User-relative path - ~/configs:/etc/configs/:ro # Named volume - datavolume:/var/lib/mysql 复制代码
长格式能够进行更精细的控制。
type
: 挂载类型 为 volume
, bind
, tmpfs
和 npipe
source
:挂载的源位置。能够是一个主机路径,一个定义于顶级 volumes 中的卷名称,等等。若是是挂载 tmpfs
则此参数无心义。target
: 容器内的挂载点路径。read_only
: 布尔值以设定卷的可写性。bind
: 配置附加的 bind 选项。
propagation
: 用于 bind 的传播模式。volume
: 配置附加的 卷 选项
nocopy
:布尔量以禁用数据复制(默认时当卷被首次建立时,容器内的内容将被复制到卷内)tmpfs
: 配置附加的 tmpfs 选项
size
: tmpfs的容量,按字节数。consistency
:挂载的一致性要求:consistent
主机和容器有一样的视图,cached
读操做被缓冲,主机视图为主体,delegated
读写操做被缓冲,容器视图为主体。version: "3.8" services: web: image: nginx:alpine ports: - "80:80" volumes: - type: volume source: mydata target: /data volume: nocopy: true - type: bind source: ./static target: /opt/app/static networks: webnet: volumes: mydata: 复制代码
长格式在 v3.2 以后可用Note
在作绑定主机目录并挂载到容器操做时,长格式语法须要你提早将主机文件夹准备就绪。使用短格式的话,对应文件夹将被就地建立,若是它还没有存在的话。详情请参阅 bind mounts documentation。
当工做在 services, swarms, 或 docker-stack.yml
场景下,要注意一个服务在 swarm 中可能被部署到任意节点,而每当服务被更新以后再次启动时,可能已经再也不在原来的节点上了。
当指定名称的卷并不存在时,Docker会自动建立一个匿名卷用于引用的服务。匿名卷是不可持久化的,所以当关联的容器实例退出并被移除时,匿名卷也会被销毁。
若是想要持久化你的数据,采用命名卷以及选择恰当的卷驱动程序,这个驱动应该是跨主机的,这样数据才能在不一样的主机之间漫游。不然的话,你应该设置服务的约束条件以便该服务只会被部署到特定的节点上,这些节点上有相应的卷服务在正确工做。
做为一个例子,votingapp sample in Docker Labs 的 docker-stack.yml
文件定义了 db
服务,运行着 postgresql。它使用了一个命名卷 db-data
来持久化数据库数据,这个卷被经过swarm约束在只能运行在 manager
这个节点上,所以一切疑难都不存在了。下面是源码:
version: "3.8" services: db: image: postgres:9.4 volumes: - db-data:/var/lib/postgresql/data networks: - backend deploy: placement: constraints: [node.role == manager] 复制代码
在 Docker 17.04 CE Edge 以及其后版本中(乃至于 17.06CE Edge 和 Stable 版本),你能够配置容器和主机之间卷如何被同步的一致性约束参数。这些标志包括:
consistent
彻底一致。主机和容器有一样的视图,这是默认的策略。
cached
宿主机为准。对卷的读操做被缓冲,主机视图为主体,
delegated
容器为准。对卷的读写操做被缓冲,容器视图为主体。
这是专为 Docker Desktop for Mac 而适配的。因为已经知道的 osxfx
的关于文件共享特性缘由,合理的设置一致性标志可以改善容器内外访问挂载卷时的性能问题。
下面是一个cached
卷的例子:
version: "3.7" services: php: image: php:7.1-fpm ports: - "9000" volumes: - .:/var/www/project:cached 复制代码
对于读写操做均被缓冲的状况,即便容器中发生了什么修改(对于向PHP Website这样的典型架构来讲,./config.php 常常是可能被写入的),也不会当即体现到宿主机中来,容器中的写入将会被堆积。
卷在容器内外的一致性问题,应该参考 Performance tuning for volume mounts (shared filesystems)。
在这里我未能原样翻译,由于那样会带来较长的篇幅,我还没有能就此问题组织好语言。
domainname
, hostname
, ipc
, mac_address
, privileged
, read_only
, shm_size
, stdin_open
, tty
, user
, working_dir
这些配置具备单一值。和 docker run
的相应命令行参数相对应。mac_address
已是被遗弃的设定。
user: postgresql working_dir: /code domainname: foo.com hostname: foo ipc: host mac_address: 02:42:ac:11:65:43 privileged: true read_only: true shm_size: 64M stdin_open: true tty: true 复制代码
有的配置选项,例如 interval
或者 timeout
(都是 check
的子选项),接受一个字符串风格的时间周期或时间段的参数值。它们应该具备这样的格式:
2.5s 10s 1m30s 2h32m 5h34m56s 复制代码
能够为数值附加的后缀单位有 us
, ms
, s
, m
, 以及 h
。
含义自明。
有的配置选项,例如 build
的子选项 shm_size
,接受一个字符串分隔的容量尺寸参数值。它们应该具备这样的格式:
2b 1024kb 2048k 300m 1gb 复制代码
有效的后缀单位包括 b
, k
, m
和 g
。此外,kb
, mb
和 gb
也是合法的。纯粹的十进制数值并不合法。
volumes
顶级的 volumes 章节能够声明和建立命名卷(无需使用 volume_from
),这些卷可以被用于在 service 章节下的 volumes 小节中被引用。因此咱们能够重用它们,甚至可以跨越多个 services。docker命令的 docker volume 子命令有更多的参考信息。
关于卷的使用,也能够参考 Use volumes 和 Volume Plugins。
这里有一个示例,包含了两个服务,数据库的数据存储文件夹在两个服务之间被共享,于是数据库可使用这个存储文件夹,而备份服务一样能够操做它以完成备份任务:
version: "3.8" services: db: image: db volumes: - data-volume:/var/lib/db backup: image: backup-service volumes: - data-volume:/var/lib/backup/data volumes: data-volume: 复制代码
顶级 volumes
章节下的条目能够是空,无需指定细节,这样的话,默认的卷驱动程序将被应用(一般都会是 local
卷驱动)。
但你也能够经过下面的参数对其进行定制:
driver
指定哪个卷驱动程序会被采用。通常来讲,默认值会是 local
。若是卷驱动程序无效、或不能工做,在 docker-compose up
时 Docker Engine将会返回一个错误。
driver: foobar 复制代码
driver_opts
可选地指定一组键值对参数集,这些参数将被传递给卷驱动程序。因此这些参数集是和卷驱动程序相关的,请参考卷驱动程序的有关文档。
volumes: example: driver_opts: type: "nfs" o: "addr=10.40.0.199,nolock,soft,rw" device: ":/docker/example" 复制代码
external
若是设置为 true
,表示相应的卷是在 compose 编排文件以外被建立就绪的。此时 docker-compse up
将不会尝试建立这个卷,而若是该卷还没有存在则会返回一个错误。
对于 v3.3 以及更低的 compose 编排格式版本而言,external
不能够被用于与其余卷配置参数组合使用,例如 driver
, driver_opts
, labels
等等。但对于 v3.4 以及更高版原本说再也不有此限制。
下面的示例中,Compose 查找一个名为 data
的外部卷并挂载它到 db
服务中,而不是尝试建立一个名为 [projectname]_data
的新卷。
version: "3.8" services: db: image: postgres volumes: - data:/var/lib/postgresql/data volumes: data: external: true 复制代码
external.name
在 v3.4+ 已被废弃,这以后直接使用name
。
你也能够单独指定卷名字(这时,data
被认为是该卷在当前编排文件中被引用时的 卷别名):
volumes:
data:
external:
name: actual-name-of-volume
复制代码
External volumes are always created with docker stack deploy
在使用 docker stack deploy 部署到 swarm 中时,外部卷若是不存在,则老是自动被建立。进一步的有关信息请参阅 moby/moby#29976、
labels
使用 Docker labels 为容器添加元数据。能够是数组格式或者字典格式。
咱们建议你使用反向DNS标注方式,为你的元数据表键添加反向域名前缀,从而避免潜在的和其它应用的相同名字的表键发生冲突:
labels: com.example.description: "Database volume" com.example.department: "IT/Ops" com.example.label-with-empty-value: "" labels: - "com.example.description=Database volume" - "com.example.department=IT/Ops" - "com.example.label-with-empty-value" 复制代码
name
since v3.4+
为卷指定一个自定义的名字。名字的值可被用于解决具备特殊字符名字的卷。注意该值被原样使用,引号不会被忽略,也不会被添加上栈名字前缀。
version: "3.8" volumes: data: name: my-app-data 复制代码
name
能够被与 external
相组合:
version: "3.8" volumes: data: external: true name: my-app-data 复制代码
networks
顶级章节 networks
使得你能够配置想要建立和使用的网络(Compose内网)。
driver
指定该网络的驱动程序。
缺省的驱动程序由 Docker Engine 的启动参数所指定。一般状况下,启动参数内置为在单节点宿主机上使用 bridge
驱动,而在 swarm mode
中使用 overlay
驱动。
若是驱动程序不可用,Docker Engine 将会返回一个错误。
driver: overlay 复制代码
bridge
缺省时 Docker 在每一个宿主机节点上使用 bridge
驱动。有关桥接网络是如何工做的,能够参考 Docker Labs 的和网络相关的辅导用例:Bridge networking。
overlay
overlay
驱动在多个 swarm mode
节点之间创建一个命名子网,这是一个跨主机的虚拟网络。
swarm mode
中如何创建 overlay
网络并籍此令服务跨主机正确工做,请参考 Docker Labs 的和网络相关的辅导用例: Overlay networking and service discovery。overlay
是如何跨主机完成虚拟网络构建和报文如何流转的,能够参考 Overlay Driver Network Architecture。host
或 none
使用主机网络栈,或者不使用网络。
和命令行参数 --net=host
以及 --net=none
是等价的。
这两种驱动及网络模型只能被用于 docker stack
之中。若是你正在使用 docker compose
相关指令,请使用 network_mode
来指定它们。
If you want to use a particular network on a common build, use [network] as mentioned in the second yaml file example.
使用内建的网络模型,例如 host
和 none
,语法上有一点点须要注意的地方:若是用 host
或 none
这样的名字定义一个外部网络(注意你并不须要真的建立他们,这二者都属于Docker内置的网络模型),那么在 Compose 编排文件中引用它们时你须要使用 hostnet
或 nonet
,如同这样:
version: "3.8" services: web: networks: hostnet: {} networks: hostnet: external: true name: host --- services: web: ... build: ... network: host context: . ... services: web: ... networks: nonet: {} networks: nonet: external: true name: none 复制代码
driver_opts
指定一组键值对表示的选项集,以传递给网络驱动程序。它们是和驱动程序密切相关的,因此具体的可用参数应该参考对应的驱动程序文档。
driver_opts: foo: "bar" baz: 1 复制代码
attachable
since v3.2+
只能用于 driver: overlay
的场景。
若是被设置为 true
,独立运行的容器也能被附着在该网络之中。若是独立运行的容器实例被附着到了一个 overlay 网络中,那么容器中的服务与单独的容器实例之间可以互相通信。请注意你甚至能够附着其余 Docker daemon 中的容器实例到本 overlay 网络中。
networks: mynet1: driver: overlay attachable: true 复制代码
enable_ipv6
在该网络/子网中启用 IPv6。
在 v3+ 中不被支持。
enable_ipv6
须要你使用 v2 的编排格式,并且也不能被用于 swarm mode 中。
ipam
自定义 IPAM 配置。每一项子配置都是可选参数。
driver
: 自定义 IPAM 驱动程序,而不使用默认值config
: 一个列表,包含一到多个配置块。每一个配置块具备下列子参数:
subnet
: CIDR格式的子网定义,以划定一个网段。一个完整的例子:
ipam: driver: default config: - subnet: 172.28.0.0/16 复制代码
NOTE:附加IPAM如
gateway
只在 v2 中可用。
internal
默认时,Docker也会链接到一个桥接网络以提供外部可链接性。若是你想创建一个外部的隔离的 overlay 网络,请设置本选项为 true
。
labels
使用 Docker labels 为容器添加元数据。能够是数组格式或者字典格式。
咱们建议你使用反向DNS标注方式,为你的元数据表键添加反向域名前缀,从而避免潜在的和其它应用的相同名字的表键发生冲突:
labels: com.example.description: "Financial transaction network" com.example.department: "Finance" com.example.label-with-empty-value: "" labels: - "com.example.description=Financial transaction network" - "com.example.department=Finance" - "com.example.label-with-empty-value" 复制代码
external
若是设置为 true
,那么本网络是在 Compose 编排文件以外被建立和管理的。此时 dockercompose up
不会试图建立它,若是网络并不存在则返回一个错误。
对于 v3.3 以及更低版本的格式,external
不可与 driver
, driver_opts
, ipam
, internal
等连用。此限制在 v3.4+ 以后被取消。
下面的例子里,proxy
是一个外部世界中的网关,Compose将会寻找经过 docker network create outside
所创建的 outside
外部网络,而不是试图去自动创建一个名为 [projectname]_outside
的新网络:
version: "3.8" services: proxy: build: ./proxy networks: - outside - default app: build: ./app networks: - default networks: outside: external: true 复制代码
external.name
在 v3.5 及以后已经被废弃,请改用name
。
你也能够单独指定一个网络名用于在Compose编排文件内被引用。
name
since v3.5
为网络设置一个自定义名字。名字的值可被用于解决具备特殊字符名字的卷。注意该值被原样使用,引号不会被忽略,也不会被添加上栈名字前缀。
version: "3.8" networks: network1: name: my-app-net 复制代码
name
能够与 external
一块儿连用:
version: "3.8" networks: network1: external: true name: my-app-net 复制代码
configs
顶级的 configs
章节声明,定义了一个配置项或者其参考,该配置项能够被受权给栈内服务使用。配置项的来源能够是 file
或 external
。
file
: 配置项的内容在一个宿主机文件中。external
: 若是设置为 true
,表示该配置项已经建立就绪了。Docker将不会试图创建它,而是在起不存在时生成一个 config not found
错误。name
: 该配置项在 Docker 中的名字。名字的值可被用于解决具备特殊字符名字的卷。注意该值被原样使用,引号不会被忽略,也不会被添加上栈名字前缀。driver
and driver_opts
: The name of a custom secret driver, and driver-specific options passed as key/value pairs. Introduced in version 3.8 file format, and only supported when using docker stack
.template_driver
: The name of the templating driver to use, which controls whether and how to evaluate the secret payload as a template. If no driver is set, no templating is used. The only driver currently supported is golang
, which uses a golang
. Introduced in version 3.8 file format, and only supported when using docker stack
. Refer to use a templated config for a examples of templated configs.下面的例子中,看成为栈的一部分被部署时,my_first_config
会被自动建立并命名为 <stack_name>_my_first_config
,至于 my_second_config
是已经存在的。
configs: my_first_config: file: ./config_data my_second_config: external: true 复制代码
另外一种变化是外部配置项带有 name
定义的状况,此时该配置项在 Compose 中能够被以 redis_config
为名进行参考和使用:
configs: my_first_config: file: ./config_data my_second_config: external: name: redis_config 复制代码
你仍需在栈内为每一个服务声明 configs
章节以得到访问配置项的权利,参考 grant access to the config。
secrets
顶级的 secrets
章节声明,定义了一个敏感信息项或者其参考,该敏感信息项能够被受权给栈内服务使用。敏感信息项的来源能够是 file
或 external
。
file
: 敏感信息项的内容在一个宿主机文件中。external
: 若是设置为 true
,表示该敏感信息项已经建立就绪了。Docker将不会试图创建它,而是在起不存在时生成一个 secret not found
错误。name
: 该敏感信息项在 Docker 中的名字。名字的值可被用于解决具备特殊字符名字的卷。注意该值被原样使用,引号不会被忽略,也不会被添加上栈名字前缀。template_driver
: The name of the templating driver to use, which controls whether and how to evaluate the secret payload as a template. If no driver is set, no templating is used. The only driver currently supported is golang
, which uses a golang
. Introduced in version 3.8 file format, and only supported when using docker stack
.下面的例子中,看成为栈的一部分被部署时,my_first_secret
会被自动建立并命名为 <stack_name>_my_first_secret
,至于 my_second_secret
是已经存在的。
secrets: my_first_secret: file: ./secret_data my_second_secret: external: true 复制代码
另外一种变化是外部配置项带有 name
定义的状况,此时该配置项在 Compose 中能够被以 redis_secret
为名进行参考和使用。
secrets: my_first_secret: file: ./secret_data my_second_secret: external: true name: redis_secret 复制代码
my_second_secret:
external:
name: redis_secret
复制代码
你仍需在栈内为每一个服务声明 secret
章节以得到访问敏感信息项的权利,参考 grant access to the secret。
Compose编排文件中可使用环境变量。当 docker-compose
运行时,Compose 从 Shell 环境变量中抽取变量值。例如,假设操做系统的环境变量中包含 POSTGRES_VERSION=9.3
的定义,那么如下定义
db: image: "postgres:${POSTGRES_VERSION}" 复制代码
等价于
db: image: "postgres:9.3" 复制代码
若是环境变量并不存在或者为空串,那么它就被当作是空字符串。
你能够经过 .env
文件来为环境变量设定缺省值。Compose 将会自动查找当前文件夹中的 .env
文件以得到环境变量的值。
IMPORTANT: 注意
.env
文件只在docker-compose up
场景中有效,而在docker stack deploy
时它并不会被使用。
两种语法 $VARIABLE
和 ${VARIABLE}
都是可用的。此外在 v2.1 格式中,相似于 Shell 语法的以下形式也能够被使用:
${VARIABLE:-default}
将会返回 default
,若是环境变量 VARIABLE
为空字符串或未被设置的话。${VARIABLE-default}
将会返回 default
,若是环境变量 VARIABLE
未被设置的话。相似地,下面的语法有助于指定一个明确的值:
${VARIABLE:?err}
将会产生错误信息 err
,若是环境变量 VARIABLE
为空或未被设置的话。${VARIABLE?err}
将会产生错误信息 err
,若是环境变量 VARIABLE
未被设置的话。其余的 Shell 语法特性并未被支持,例如 ${VARIABLE/foo/bar}
。
若是须要一个美圆符号的话,请使用 ?
。此时 ?
再也不参与环境变量替换的解释。以下例:
web: build: . command: "?VAR_NOT_INTERPOLATED_BY_COMPOSE" 复制代码
若是你忘记了这个规则而使用了一个 $
单个字符的话,Compose 会警告你:
The VAR_NOT_INTERPOLATED_BY_COMPOSE is not set. Substituting an empty string.
since v3.4
经过扩展字段,可以重用编排配置片断。它们能够是自由的格式,前提是你将它们定义在 yaml 文档的顶级,而且其章节名以 x-
开头:
version: '3.4' x-custom: items: - a - b options: max-size: '12m' name: "custom" 复制代码
NOTE
从 v3.7 开始(对于 3.x 系列),或者从 v2.4 开始(对于 2.x 系列),扩展字段也能够被放在 服务,卷,网络,配置项以及敏感信息项顶级章节之下的第一级。
如同这样:
version: '3.7' services: redis: # ... x-custom: items: - a - b options: max-size: '12m' name: "custom" 复制代码
所谓的自由格式,是指这些定义并不被 Compose 所解释。然而当你在某个地方插入它们的引用时,它们会被展开到插入点,而后再结合上下文被 Compose 解释具体的语义。这使用了 YAML anchors 语法。
例如,若是你的多个服务都会使用相同的日志记录选项:
logging: options: max-size: '12m' max-file: '5' driver: json-file 复制代码
你能够这样定义:
x-logging: &default-logging options: max-size: '12m' max-file: '5' driver: json-file services: web: image: myapp/web:latest logging: *default-logging db: image: mysql:latest logging: *default-logging 复制代码
经过 YAML merge type 语法,你也能够在插入扩展字段定义是覆盖某些子选项。例如:
version: '3.4' x-volumes: &default-volume driver: foobar-storage services: web: image: myapp/web:latest volumes: ["vol1", "vol2", "vol3"] volumes: vol1: *default-volume vol2: << : *default-volume name: volume02 vol3: << : *default-volume driver: default name: volume-local 复制代码
🔚