合併

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 命令

當合併使用 services 屬性 commandentrypointhealthcheck: `test` 的 Compose 檔案時,該值會被最新的 Compose 檔案覆寫,而不是附加。

合併以下 YAML 樹範例

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

會產生一個等價於以下 YAML 樹的 Compose 應用程式模型

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

唯一資源

適用於 portsvolumessecretsconfigs 等 services 屬性。雖然這些類型在 Compose 檔案中被塑模為序列,但它們有特殊的唯一性要求

屬性唯一鍵
volumestarget(目標)
secretssource(來源)
configssource(來源)
source(來源)ports

合併 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" 

如果沒有使用 `!override`,根據上述的合併規則,`8080:80` 和 `8443:443` 都會被公開。

其他資源

關於如何使用合併來建立複合 Compose 檔案的更多資訊,請參閱 使用多個 Compose 檔案