覆蓋配置

Bake 支援從檔案載入構建定義,但有時您需要更大的靈活性來配置這些定義。例如,您可能希望在特定環境或針對特定目標進行構建時覆蓋某個屬性。

以下屬性可以被覆蓋:

  • args
  • attest
  • cache-from
  • cache-to
  • context
  • contexts
  • dockerfile
  • entitlements
  • labels
  • 網路
  • no-cache
  • output
  • platform
  • pull
  • secrets
  • ssh
  • tags
  • target

要覆蓋這些屬性,您可以使用以下方法:

檔案覆蓋

您可以載入多個 Bake 檔案,這些檔案定義了目標的構建配置。當您希望將配置分離到不同的檔案中以實現更好的組織,或根據載入的檔案有條件地覆蓋配置時,這非常有用。

預設檔案查詢

您可以使用 --file-f 標誌來指定要載入的檔案。如果您未指定任何檔案,Bake 將使用以下查詢順序:

  1. compose.yaml
  2. compose.yml
  3. docker-compose.yml
  4. docker-compose.yaml
  5. docker-bake.json
  6. docker-bake.hcl
  7. docker-bake.override.json
  8. docker-bake.override.hcl

如果找到多個 Bake 檔案,所有檔案都將被載入併合併到一個定義中。檔案將按照查詢順序進行合併。

$ docker buildx bake --print
[+] Building 0.0s (1/1) FINISHED                                                                                                                                                                                            
 => [internal] load local bake definitions                                                                                                                                                                             0.0s
 => => reading compose.yaml 45B / 45B                                                                                                                                                                                  0.0s
 => => reading docker-bake.hcl 113B / 113B                                                                                                                                                                             0.0s
 => => reading docker-bake.override.hcl 65B / 65B

如果合併的檔案包含重複的屬性定義,這些定義將根據屬性進行合併或被最後出現的定義覆蓋。

Bake 將嘗試按照找到的順序載入所有檔案。如果多個檔案定義了相同的目標,則屬性將被合併或覆蓋。在覆蓋的情況下,最後載入的檔案優先。

例如,給定以下檔案:

docker-bake.hcl
variable "TAG" {
  default = "foo"
}

target "default" {
  tags = ["username/my-app:${TAG}"]
}
docker-bake.override.hcl
variable "TAG" {
  default = "bar"
}

由於 docker-bake.override.hcl 在預設查詢順序中最後載入,TAG 變數被值 bar 覆蓋。

$ docker buildx bake --print
{
  "target": {
    "default": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "tags": ["username/my-app:bar"]
    }
  }
}

手動檔案覆蓋

您可以使用 --file 標誌顯式指定要載入的檔案,並將其作為有條件地應用覆蓋檔案的一種方式。

例如,您可以建立一個檔案,為特定環境定義一組配置,並僅在該環境進行構建時載入它。以下示例展示瞭如何載入一個 override.hcl 檔案,該檔案將 TAG 變數設定為 bar。然後,TAG 變數在 default 目標中使用。

docker-bake.hcl
variable "TAG" {
  default = "foo"
}

target "default" {
  tags = ["username/my-app:${TAG}"]
}
overrides.hcl
variable "TAG" {
  default = "bar"
}

在不帶 --file 標誌的情況下列印構建配置,顯示 TAG 變數設定為預設值 foo

$ docker buildx bake --print
{
  "target": {
    "default": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "tags": [
        "username/my-app:foo"
      ]
    }
  }
}

使用 --file 標誌載入 overrides.hcl 檔案將用值 bar 覆蓋 TAG 變數。

$ docker buildx bake -f docker-bake.hcl -f overrides.hcl --print
{
  "target": {
    "default": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "tags": [
        "username/my-app:bar"
      ]
    }
  }
}

命令列

您還可以使用 --set 標誌 從命令列覆蓋目標配置。

# docker-bake.hcl
target "app" {
  args = {
    mybuildarg = "foo"
  }
}
$ docker buildx bake --set app.args.mybuildarg=bar --set app.platform=linux/arm64 app --print
{
  "group": {
    "default": {
      "targets": ["app"]
    }
  },
  "target": {
    "app": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "args": {
        "mybuildarg": "bar"
      },
      "platforms": ["linux/arm64"]
    }
  }
}

還支援 https://golang.org.tw/pkg/path/#Match 中定義的模式匹配語法。

$ docker buildx bake --set foo*.args.mybuildarg=value  # overrides build arg for all targets starting with "foo"
$ docker buildx bake --set *.platform=linux/arm64      # overrides platform for all targets
$ docker buildx bake --set foo*.no-cache               # bypass caching only for targets starting with "foo"

可以使用 --set 覆蓋的完整屬性列表是:

  • args
  • attest
  • cache-from
  • cache-to
  • context
  • contexts
  • dockerfile
  • entitlements
  • labels
  • 網路
  • no-cache
  • output
  • platform
  • pull
  • secrets
  • ssh
  • tags
  • target

環境變數

您還可以使用環境變數來覆蓋配置。

Bake 允許您使用環境變數來覆蓋 variable 塊的值。只有 variable 塊可以透過環境變數覆蓋。這意味著您需要在 Bake 檔案中定義變數,然後設定同名的環境變數來覆蓋它。

以下示例展示瞭如何在 Bake 檔案中定義一個帶有預設值的 TAG 變數,並使用環境變數覆蓋它。

variable "TAG" {
  default = "latest"
}

target "default" {
  context = "."
  dockerfile = "Dockerfile"
  tags = ["docker.io/username/webapp:${TAG}"]
}
$ export TAG=$(git rev-parse --short HEAD)
$ docker buildx bake --print webapp

TAG 變數被環境變數的值覆蓋,該值是 git rev-parse --short HEAD 生成的短提交雜湊。

{
  "group": {
    "default": {
      "targets": ["webapp"]
    }
  },
  "target": {
    "webapp": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "tags": ["docker.io/username/webapp:985e9e9"]
    }
  }
}

型別強制轉換

支援使用環境變數覆蓋非字串變數。作為環境變數傳遞的值將首先被強制轉換為適當的型別。

以下示例定義了一個 PORT 變數。backend 目標按原樣使用 PORT 變數,而 frontend 目標使用 PORT 的值加一。

variable "PORT" {
  default = 3000
}

group "default" {
  targets = ["backend", "frontend"]
}

target "backend" {
  args = {
    PORT = PORT
  }
}

target "frontend" {
  args = {
    PORT = add(PORT, 1)
  }
}

使用環境變數覆蓋 PORT 會在 frontend 目標執行表示式之前,首先將值強制轉換為預期型別(一個整數)。

$ PORT=7070 docker buildx bake --print
{
  "group": {
    "default": {
      "targets": [
        "backend",
        "frontend"
      ]
    }
  },
  "target": {
    "backend": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "args": {
        "PORT": "7070"
      }
    },
    "frontend": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "args": {
        "PORT": "7071"
      }
    }
  }
}