docker-compose文件属性(10)合并
·
Compose 允许您通过多个 Compose 文件来定义应用模型。当使用多个文件时,Compose 会遵循特定规则来合并这些文件。
- 映射(Mapping)的合并:YAML 映射通过 添加缺失的条目 和 合并冲突的条目 来实现合并。
# 文件 1
services:
foo:
key1: value1
key2: value2
# 文件 2
services:
foo:
key2: VALUE # 此值将覆盖上一个文件的 value2
key3: value3
合并结果为:
services:
foo:
key1: value1
key2: VALUE # 来自第二个文件
key3: value3 # 来自第二个文件
- 序列(Sequence)的合并:YAML 序列通过 将后续文件的值追加 到前一个文件的序列中来实现合并。
合并以下示例:
# 文件 1
services:
foo:
DNS:
- 1.1.1.1
# 文件 2
services:
foo:
DNS:
- 8.8.8.8
合并结果为:
services:
foo:
DNS:
- 1.1.1.1 # 来自第一个文件
- 8.8.8.8 # 来自第二个文件,被追加
- 特殊规则(例外情况)
- Shell 命令属性:对于服务属性 command、entrypoint 和 healthcheck: test,合并时最新(后面)的 Compose 文件的值会完全覆盖前一个文件的值,而不是追加。合并以下示例:
# 文件 1
services:
foo:
command: ["echo", "foo"]
# 文件 2
services:
foo:
command: ["echo", "bar"]
合并结果为:
services:
foo:
command: ["echo", "bar"] # 来自第二个文件,覆盖了第一个
- 唯一资源属性:适用于 ports、volumes、secrets 和 configs 这些服务属性。虽然它们在 Compose 文件中以序列形式表示,但有特殊的唯一性约束:
|
属性 |
唯一性判断依据 |
|
volumes |
target (容器内的目标路径) |
|
secrets |
target |
|
configs |
target |
|
ports |
{ip, target, published, protocol} 的组合 |
合并文件时,Compose 会追加不违反唯一性约束的新条目,并合并共享同一“唯一键”的条目。合并以下示例:
# 文件 1
services:
foo:
volumes:
- foo:/work # target 是 /work
# 文件 2
services:
foo:
volumes:
- bar:/work # target 也是 /work,唯一键冲突
合并结果为:
services:
foo:
volumes:
- bar:/work # 第二个文件的值覆盖了第一个,因为 target (/work) 相同
- 重置值(!reset):除了前面描述的机制外,覆盖(Override)Compose 文件也可用于从您的应用模型中移除元素。为此,可以使用自定义的 YAML 标签 !reset 来覆盖被覆盖 Compose 文件中设置的值。虽然必须为该属性提供一个有效的值,但该值会被忽略,目标属性将被设置为该类型的默认值或 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 # 移除 FOO 环境变量
合并结果为:
services:
app:
image: myapp
# ports 和 environment 下的 FOO 已被移除
- 替换值(!override):要求:Docker Compose 2.24.4 或更高版本。虽然 !reset 可用于移除声明,但 !override 允许您完全替换一个属性,绕过标准的合并规则。一个典型的用例是:用相同名称但完全不同的模型来替换某个资源定义。
基础文件 compose.yaml:
services:
app:
image: myapp
ports:
- "8080:80"
覆盖文件:
services:
app:
ports: !override # 使用 !override 标签
- "8443:443" # 这将完全替换之前的端口列表
合并结果为:
services:
app:
image: myapp
ports:
- "8443:443" # 只有这个端口,之前的 “8080:80” 被完全替换
如果这里没有使用 !override,根据前面的合并规则,结果将会是 "8080:80" 和 "8443:443" 两个端口并存。
更多推荐
所有评论(0)