合并

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文件时 command, entrypointhealthcheck: test, 值会被最新的Compose文件覆盖,而不是追加。

合并以下示例YAML树:

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

在Compose应用程序模型中产生与YAML树等效的结果:

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

独特资源

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

AttributeUnique key
volumestarget
secretssource
configssource
ports{ip, target, published, protocol}

在合并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

替换值

Introduced in Docker Compose version 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文件