合并

Compose 允许你通过多个 Compose 文件定义一个 Compose 应用模型。 在这样做时,Compose 遵循特定的规则来合并 Compose 文件。

这些规则概述如下。

映射

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

合并以下示例 YAML 树:

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

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

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

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

services:
  foo:
    DNS:
      - 1.1.1.1
      - 8.8.8.8

异常

Shell 命令

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

合并以下示例 YAML 树:

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

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

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

独特资源

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

属性唯一密钥
目标
密钥
配置
端口{ip, 目标, 发布时间, 协议}

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

合并以下示例 YAML 树:

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

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

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" 

如果未使用!override,则8080:808443:443将作为上述合并规则所规定的那样暴露出来。

其他资源

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