合并 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 应用调整为类生产环境(可能是生产、预发布或持续集成环境)。 为了支持这些差异,您可以将 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 支持为应用模型中包含的多种资源使用相对路径:服务镜像的构建上下文、定义环境变量的文件位置,以及用于绑定挂载卷的本地目录路径。 受此限制,在单体仓库(monorepo)中进行代码组织可能会变得困难,因为自然的选择是为每个团队或组件设立专用文件夹,但这样会导致 Compose 文件中的相对路径失效。