合并 Compose 文件
Docker Compose 允许您合并和覆盖一组 Compose 文件以创建组合的 Compose 文件。
默认情况下,Compose 读取两个文件,一个 `compose.yaml` 和一个可选的 `compose.override.yaml` 文件。按照约定,`compose.yaml` 包含您的基本配置。覆盖文件可以包含对现有服务的配置覆盖或全新的服务。
如果在两个文件中都定义了服务,Compose 将使用下面和Compose 规范中描述的规则合并配置。
如何合并多个 Compose 文件
要使用多个覆盖文件,或使用不同名称的覆盖文件,您可以使用预定义的COMPOSE_FILE环境变量,或使用 `-f` 选项指定文件列表。
Compose 按命令行上指定的顺序合并文件。后续文件可以合并、覆盖或添加到其前身。
例如
$ docker compose -f compose.yaml -f compose.admin.yaml run backup_db
`compose.yaml` 文件可能指定一个 `webapp` 服务。
webapp:
image: examples/web
ports:
- "8000:8000"
volumes:
- "/data"
`compose.admin.yaml` 也可能指定此相同的服务
webapp:
environment:
- DEBUG=1
任何匹配的字段都将覆盖之前的文件。新值添加到 `webapp` 服务配置中
webapp:
image: examples/web
ports:
- "8000:8000"
volumes:
- "/data"
environment:
- DEBUG=1
合并规则
路径相对于基本文件进行评估。当您使用多个 Compose 文件时,必须确保文件中的所有路径都相对于基本 Compose 文件(使用 `-f` 指定的第一个 Compose 文件)。这是必需的,因为覆盖文件不必是有效的 Compose 文件。覆盖文件可以包含少量配置片段。跟踪哪个服务片段相对于哪个路径是困难且令人困惑的,因此为了使路径更容易理解,所有路径都必须相对于基本文件定义。
提示
您可以使用 `docker compose config` 查看合并后的配置并避免与路径相关的問題。
Compose 将配置从原始服务复制到本地服务。如果在原始服务和本地服务中都定义了配置选项,则本地值将替换或扩展原始值。
对于 `image`、`command` 或 `mem_limit` 等单值选项,新值将替换旧值。
原始服务
services: myservice: # ... command: python app.py
本地服务
services: myservice: # ... command: python otherapp.py
结果
services: myservice: # ... command: python otherapp.py
对于 `ports`、`expose`、`external_links`、`dns`、`dns_search` 和 `tmpfs` 等多值选项,Compose 会连接两组值。
原始服务
services: myservice: # ... expose: - "3000"
本地服务
services: myservice: # ... expose: - "4000" - "5000"
结果
services: myservice: # ... expose: - "3000" - "4000" - "5000"
对于 `environment`、`labels`、`volumes` 和 `devices`,Compose 将条目“合并”在一起,其中本地定义的值优先。对于 `environment` 和 `labels`,环境变量或标签名称决定使用哪个值。
原始服务
services: myservice: # ... environment: - FOO=original - BAR=original
本地服务
services: myservice: # ... environment: - BAR=local - BAZ=local
结果
services: myservice: # ... environment: - FOO=original - BAR=local - BAZ=local
使用容器中的挂载路径合并 `volumes` 和 `devices` 的条目。
原始服务
services: myservice: # ... volumes: - ./original:/foo - ./original:/bar
本地服务
services: myservice: # ... volumes: - ./local:/bar - ./local:/baz
结果
services: myservice: # ... volumes: - ./original:/foo - ./local:/bar - ./local:/baz
有关更多合并规则,请参阅 Compose 规范中的合并和覆盖。
附加信息
使用 `-f` 是可选的。如果未提供,Compose 将在工作目录及其父目录中搜索 `compose.yaml` 和 `compose.override.yaml` 文件。您必须至少提供 `compose.yaml` 文件。如果两个文件都存在于同一目录级别,Compose 会将它们组合成单个配置。
您可以使用 `-f` 和 `-`(短划线)作为文件名从 `stdin` 读取配置。例如
$ docker compose -f - <<EOF webapp: image: examples/web ports: - "8000:8000" volumes: - "/data" environment: - DEBUG=1 EOF
使用 `stdin` 时,配置中的所有路径都相对于当前工作目录。
您可以使用
-f
标志指定 Compose 文件的路径,该文件不必位于当前目录中,可以通过命令行或在 shell 或环境文件中设置COMPOSE_FILE 环境变量来实现。例如,如果您正在运行Compose Rails 示例,并在名为
sandbox/rails
的目录中有一个compose.yaml
文件。您可以使用类似于docker compose pull的命令,通过使用-f
标志如下所示,从任何位置获取db
服务的 postgres 镜像:docker compose -f ~/sandbox/rails/compose.yaml pull db
以下是完整的示例
$ docker compose -f ~/sandbox/rails/compose.yaml pull db Pulling db (postgres:latest)... latest: Pulling from library/postgres ef0380f84d05: Pull complete 50cf91dc1db8: Pull complete d3add4cd115c: Pull complete 467830d8a616: Pull complete 089b9db7dc57: Pull complete 6fba0a36935c: Pull complete 81ef0e73c953: Pull complete 338a6c4894dc: Pull complete 15853f32f67c: Pull complete 044c83d92898: Pull complete 17301519f133: Pull complete dcca70822752: Pull complete cecf11b8ccf3: Pull complete Digest: sha256:1364924c753d5ff7e2260cd34dc4ba05ebd40ee8193391220be0f9901d4e1651 Status: Downloaded newer image for postgres:latest
示例
多个文件的常见用例是将开发 Compose 应用程序更改为类似生产的环境(可能是生产、暂存或 CI)。为了支持这些差异,您可以将 Compose 配置拆分成几个不同的文件。
首先创建一个定义服务规范配置的基文件。
compose.yaml
services:
web:
image: example/my_web_app:latest
depends_on:
- db
- cache
db:
image: postgres:latest
cache:
image: redis:latest
在这个示例中,开发配置将一些端口暴露给主机,将我们的代码作为卷挂载,并构建 web 镜像。
compose.override.yaml
services:
web:
build: .
volumes:
- '.:/code'
ports:
- 8883:80
environment:
DEBUG: 'true'
db:
command: '-d'
ports:
- 5432:5432
cache:
ports:
- 6379:6379
运行docker compose up
时,它会自动读取覆盖配置。
要在生产环境中使用此 Compose 应用程序,将创建另一个覆盖文件,该文件可能存储在不同的 Git 仓库中或由不同的团队管理。
compose.prod.yaml
services:
web:
ports:
- 80:80
environment:
PRODUCTION: 'true'
cache:
environment:
TTL: '500'
要使用此生产 Compose 文件进行部署,您可以运行
$ docker compose -f compose.yaml -f compose.prod.yaml up -d
这将使用compose.yaml
和compose.prod.yaml
中的配置部署所有三个服务,但不使用compose.override.yaml
中的开发配置。
更多信息,请参见在生产环境中使用 Compose。
限制
Docker Compose 支持应用程序模型中许多要包含的资源的相对路径:服务镜像的构建上下文、定义环境变量的文件位置、在绑定挂载卷中使用的本地目录的路径。在这种约束下,单体仓库中的代码组织可能会变得困难,因为自然的做法是为每个团队或组件创建专用文件夹,但是,Compose 文件的相对路径就会变得不相关。