覆蓋配置
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 將使用以下查詢順序:
compose.yaml
compose.yml
docker-compose.yml
docker-compose.yaml
docker-bake.json
docker-bake.hcl
docker-bake.override.json
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 將嘗試按照找到的順序載入所有檔案。如果多個檔案定義了相同的目標,則屬性將被合併或覆蓋。在覆蓋的情況下,最後載入的檔案優先。
例如,給定以下檔案:
variable "TAG" {
default = "foo"
}
target "default" {
tags = ["username/my-app:${TAG}"]
}
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
目標中使用。
variable "TAG" {
default = "foo"
}
target "default" {
tags = ["username/my-app:${TAG}"]
}
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"
}
}
}
}