合并

Compose 允许您通过多个 Compose 文件定义 Compose 应用程序模型。这样做时,Compose 会遵循特定规则来合并 Compose 文件。

以下概述了这些规则。

映射

YAML mapping 通过添加缺少的条目并合并冲突的条目进行合并。

合并以下示例 YAML 树

services:
  foo:
    key1: value1
    key2: value2
services:
  foo:
    key2: VALUE
    key3: value3

生成与 YAML 树等效的 Compose 应用程序模型

services:
  foo:
    key1: value1
    key2: VALUE
    key3: value3

序列

YAML sequence 通过将覆盖 Compose 文件中的值追加到前一个文件进行合并。

合并以下示例 YAML 树

services:
  foo:
    DNS:
      - 1.1.1.1
services:
  foo:
    DNS: 
      - 8.8.8.8

生成与 YAML 树等效的 Compose 应用程序模型

services:
  foo:
    DNS:
      - 1.1.1.1
      - 8.8.8.8

异常

Shell 命令

当合并使用服务属性 commandentrypointhealthcheck: test 的 Compose 文件时,该值将被最新 Compose 文件覆盖,而不是追加。

合并以下示例 YAML 树

services:
  foo:
    command: ["echo", "foo"]
services:
  foo:
    command: ["echo", "bar"]

生成与 YAML 树等效的 Compose 应用程序模型

services:
  foo:
    command: ["echo", "bar"]

唯一资源

适用于portsvolumessecretsconfigs 服务属性。虽然这些类型在 Compose 文件中被建模为一个序列,但它们具有特殊的唯一性要求。

属性唯一键
volumestarget
secretssource
configssource
ports{ip, target, published, protocol}

合并 Compose 文件时,Compose 会追加不违反唯一性约束的新条目,并合并共享唯一键的条目。

合并以下示例 YAML 树

services:
  foo:
    volumes:
      - foo:/work
services:
  foo:
    volumes:
      - bar:/work

生成与 YAML 树等效的 Compose 应用程序模型

services:
  foo:
    volumes:
      - bar:/work

重置值

除了上述机制之外,覆盖 Compose 文件还可以用于从应用程序模型中删除元素。为此,可以使用自定义的 YAML 标签 !reset 可以设置为覆盖覆盖 Compose 文件设置的值。属性必须提供有效的值,但会被忽略,目标属性将被设置为类型的默认值或 null

为了可读性,建议显式将属性值设置为 null(null)或空数组 [](使用 !reset null!reset []),以便清楚地表明结果属性将被清除。

基本 compose.yaml 文件

services:
  app:
    image: myapp
    ports:
      - "8080:80" 
    environment:
      FOO: BAR           

以及 compose.override.yaml 文件

services:
  app:
    image: myapp
    ports: !reset []
    environment:
      FOO: !reset null

结果为

services:
  app:
    image: myapp

替换值

在 Docker Compose 版本 2.24.4 中引入

虽然 !reset 可以用于使用覆盖文件从 Compose 文件中删除声明,但 !override 允许你完全替换属性,绕过标准合并规则。一个典型的例子是完全替换资源定义,以便依赖于不同的模型,但使用相同的名称。

基本 compose.yaml 文件

services:
  app:
    image: myapp
    ports:
      - "8080:80"            

要删除原始端口,但公开一个新的端口,可以使用以下覆盖文件

services:
  app:
    ports: !override
      - "8443:443" 

这将导致

services:
  app:
    image: myapp
    ports:
      - "8443:443" 

如果没有使用 !override8080:808443:443 将根据上面概述的合并规则被公开。

其他资源

有关如何使用合并创建复合 Compose 文件的更多信息,请参阅使用多个 Compose 文件