Bake 檔案參考
Bake 檔案是用於定義使用 docker buildx bake
執行的工作流的檔案。
檔案格式
您可以使用以下檔案格式定義您的 Bake 檔案
- HashiCorp 配置語言 (HCL)
- JSON
- YAML (Compose 檔案)
預設情況下,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
您可以使用 --file
標誌明確指定檔案位置
$ docker buildx bake --file ../docker/bake.hcl --print
如果您未明確指定檔案,Bake 會在當前工作目錄中搜索檔案。如果找到多個 Bake 檔案,所有檔案將合併為一個定義。檔案按照查詢順序合併。這意味著如果您的專案同時包含 compose.yaml
檔案和 docker-bake.hcl
檔案,Bake 會首先載入 compose.yaml
檔案,然後載入 docker-bake.hcl
檔案。
如果合併的檔案包含重複的屬性定義,這些定義將根據屬性進行合併或被最後出現的定義覆蓋。以下屬性被最後出現的定義覆蓋
target.cache-to
target.dockerfile-inline
target.dockerfile
target.outputs
target.platforms
target.pull
target.tags
target.target
例如,如果 compose.yaml
和 docker-bake.hcl
都定義了 tags
屬性,則使用 docker-bake.hcl
中的定義。
$ cat compose.yaml
services:
webapp:
build:
context: .
tags:
- bar
$ cat docker-bake.hcl
target "webapp" {
tags = ["foo"]
}
$ docker buildx bake --print webapp
{
"group": {
"default": {
"targets": [
"webapp"
]
}
},
"target": {
"webapp": {
"context": ".",
"dockerfile": "Dockerfile",
"tags": [
"foo"
]
}
}
}
所有其他屬性都將合併。例如,如果 compose.yaml
和 docker-bake.hcl
都為 labels
屬性定義了唯一的條目,則所有條目都將被包含。相同標籤的重複條目將被覆蓋。
$ cat compose.yaml
services:
webapp:
build:
context: .
labels:
com.example.foo: "foo"
com.example.name: "Alice"
$ cat docker-bake.hcl
target "webapp" {
labels = {
"com.example.bar" = "bar"
"com.example.name" = "Bob"
}
}
$ docker buildx bake --print webapp
{
"group": {
"default": {
"targets": [
"webapp"
]
}
},
"target": {
"webapp": {
"context": ".",
"dockerfile": "Dockerfile",
"labels": {
"com.example.foo": "foo",
"com.example.bar": "bar",
"com.example.name": "Bob"
}
}
}
}
語法
Bake 檔案支援以下屬性型別
target
:構建目標group
:構建目標的集合variable
:構建引數和變數function
:自定義 Bake 函式
您將屬性定義為 Bake 檔案中的分層塊。您可以為一個屬性分配一個或多個屬性。
以下程式碼片段顯示了一個簡單 Bake 檔案的 JSON 表示。此 Bake 檔案定義了三個屬性:一個變數、一個組和一個目標。
{
"variable": {
"TAG": {
"default": "latest"
}
},
"group": {
"default": {
"targets": ["webapp"]
}
},
"target": {
"webapp": {
"dockerfile": "Dockerfile",
"tags": ["docker.io/username/webapp:${TAG}"]
}
}
}
在 Bake 檔案的 JSON 表示中,屬性是物件,而屬性是分配給這些物件的值。
以下示例顯示了相同 Bake 檔案的 HCL 格式
variable "TAG" {
default = "latest"
}
group "default" {
targets = ["webapp"]
}
target "webapp" {
dockerfile = "Dockerfile"
tags = ["docker.io/username/webapp:${TAG}"]
}
HCL 是 Bake 檔案的首選格式。除了語法差異外,HCL 允許您使用 JSON 和 YAML 格式不支援的功能。
本文件中的示例使用 HCL 格式。
目標
目標反映單個 docker build
呼叫。考慮以下構建命令
$ docker build \
--file=Dockerfile.webapp \
--tag=docker.io/username/webapp:latest \
https://github.com/username/webapp
您可以在 Bake 檔案中表達此命令如下
target "webapp" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
context = "https://github.com/username/webapp"
}
下表顯示了您可以分配給目標的完整屬性列表
名稱 | 型別 | 描述 |
---|---|---|
args | 對映 | 構建引數 |
annotations | 列表 | 匯出器註釋 |
attest | 列表 | 構建證明 |
cache-from | 列表 | 外部快取源 |
cache-to | 列表 | 外部快取目標 |
call | 字串 | 指定要為目標呼叫的前端方法。 |
context | 字串 | 位於指定路徑或 URL 中的檔案集 |
contexts | 對映 | 額外的構建上下文 |
description | 字串 | 目標的描述 |
dockerfile-inline | 字串 | 內聯 Dockerfile 字串 |
dockerfile | 字串 | Dockerfile 位置 |
entitlements | 列表 | 構建過程執行所需的許可權 |
extra-hosts | 列表 | 自定義主機到 IP 對映 |
inherits | 列表 | 從其他目標繼承屬性 |
labels | 對映 | 影像元資料 |
matrix | 對映 | 定義一組變數,將一個目標分叉為多個目標。 |
name | 字串 | 使用矩陣時覆蓋目標名稱。 |
no-cache-filter | 列表 | 停用特定階段的構建快取 |
no-cache | 布林值 | 完全停用構建快取 |
output | 列表 | 輸出目標 |
platforms | 列表 | 目標平臺 |
pull | 布林值 | 始終拉取映象 |
secret | 列表 | 要暴露給構建的秘密 |
shm-size | 列表 | /dev/shm 的大小 |
ssh | 列表 | 要暴露給構建的 SSH 代理套接字或金鑰 |
tags | 列表 | 映象名稱和標籤 |
target | 字串 | 目標構建階段 |
ulimits | 列表 | Ulimit 選項 |
target.args
使用 args
屬性為目標定義構建引數。這與向構建命令傳遞 --build-arg
標誌具有相同的效果。
target "default" {
args = {
VERSION = "0.0.0+unknown"
}
}
您可以將 args
屬性設定為使用 null
值。這樣做會強制 target
使用 Dockerfile 中指定的 ARG
值。
variable "GO_VERSION" {
default = "1.20.3"
}
target "webapp" {
dockerfile = "webapp.Dockerfile"
tags = ["docker.io/username/webapp"]
}
target "db" {
args = {
GO_VERSION = null
}
dockerfile = "db.Dockerfile"
tags = ["docker.io/username/db"]
}
target.annotations
annotations
屬性允許您向使用 bake 構建的映象添加註釋。該鍵接受一個註釋列表,格式為 KEY=VALUE
。
target "default" {
output = [{ type = "image", name = "foo" }]
annotations = ["org.opencontainers.image.authors=dvdksn"]
}
預設情況下,註釋會新增到映象清單中。您可以透過向註釋新增字首來配置註釋的級別,該字首包含您要註釋的所有級別的逗號分隔列表。以下示例將註釋同時新增到映象索引和清單中。
target "default" {
output = [
{
type = "image"
name = "foo"
}
]
annotations = ["index,manifest:org.opencontainers.image.authors=dvdksn"]
}
請閱讀 指定註釋級別 中支援的級別。
target.attest
attest
屬性允許您將 構建證明 應用於目標。此屬性接受證明引數的長格式 CSV 版本。
target "default" {
attest = [
{
type = "provenance"
mode = "max"
},
{
type = "sbom"
}
]
}
target.cache-from
構建快取源。構建器從您指定的位置匯入快取。它使用 Buildx 快取儲存後端,其工作方式與 --cache-from
標誌相同。這接受一個列表值,因此您可以指定多個快取源。
target "app" {
cache-from = [
{
type = "s3"
region = "eu-west-1"
bucket = "mybucket"
},
{
type = "registry"
ref = "user/repo:cache"
}
]
}
target.cache-to
構建快取匯出目標。構建器將其構建快取匯出到您指定的位置。它使用 Buildx 快取儲存後端,其工作方式與 --cache-to
標誌 相同。這接受一個列表值,因此您可以指定多個快取匯出目標。
target "app" {
cache-to = [
{
type = "s3"
region = "eu-west-1"
bucket = "mybucket"
},
{
type = "inline"
}
]
}
target.call
指定要使用的前端方法。例如,前端方法允許您僅執行構建檢查,而不是執行構建。這與 --call
標誌相同。
target "app" {
call = "check"
}
支援的值有
有關前端方法的更多資訊,請參閱 docker buildx build --call
的 CLI 參考。
target.context
指定此目標要使用的構建上下文的位置。接受 URL 或目錄路徑。這與您傳遞給構建命令的 構建上下文 位置引數相同。
target "app" {
context = "./src/www"
}
預設情況下,這會解析為當前工作目錄("."
)。
$ docker buildx bake --print -f - <<< 'target "default" {}'
[+] Building 0.0s (0/0)
{
"target": {
"default": {
"context": ".",
"dockerfile": "Dockerfile"
}
}
}
target.contexts
附加構建上下文。這與 --build-context
標誌 相同。此屬性接受一個對映,其中鍵生成您可以在構建中引用的命名上下文。
您可以指定不同型別的上下文,例如本地目錄、Git URL,甚至其他 Bake 目標。Bake 會根據上下文值的模式自動確定上下文的型別。
上下文型別 | 示例 |
---|---|
容器映象 | docker-image://alpine@sha256:0123456789 |
Git URL | https://github.com/user/proj.git |
HTTP URL | https://example.com/files |
本地目錄 | ../path/to/src |
Bake 目標 | target:base |
固定映象版本
# docker-bake.hcl
target "app" {
contexts = {
alpine = "docker-image://alpine:3.13"
}
}
# Dockerfile
FROM alpine
RUN echo "Hello world"
使用本地目錄
# docker-bake.hcl
target "app" {
contexts = {
src = "../path/to/source"
}
}
# Dockerfile
FROM scratch AS src
FROM golang
COPY --from=src . .
使用另一個目標作為基礎
注意您應該優先使用常規的多階段構建,而不是此選項。當您有多個 Dockerfile 無法輕易合併為一個時,可以使用此功能。
# docker-bake.hcl
target "base" {
dockerfile = "baseapp.Dockerfile"
}
target "app" {
contexts = {
baseapp = "target:base"
}
}
# Dockerfile
FROM baseapp
RUN echo "Hello world"
target.description
為目標定義一個人類可讀的描述,闡明其目的或功能。
target "lint" {
description = "Runs golangci-lint to detect style errors"
args = {
GOLANGCI_LINT_VERSION = null
}
dockerfile = "lint.Dockerfile"
}
當與 docker buildx bake --list=targets
選項結合使用時,此屬性非常有用,可以在列出 Bake 檔案中可用的構建目標時提供更多資訊輸出。
target.dockerfile-inline
使用字串值作為構建目標的內聯 Dockerfile。
target "default" {
dockerfile-inline = "FROM alpine\nENTRYPOINT [\"echo\", \"hello\"]"
}
dockerfile-inline
優先於 dockerfile
屬性。如果您同時指定兩者,Bake 將使用內聯版本。
target.dockerfile
用於構建的 Dockerfile 名稱。這與 docker build
命令的 --file
標誌 相同。
target "default" {
dockerfile = "./src/www/Dockerfile"
}
預設情況下,解析為 "Dockerfile"
。
$ docker buildx bake --print -f - <<< 'target "default" {}'
[+] Building 0.0s (0/0)
{
"target": {
"default": {
"context": ".",
"dockerfile": "Dockerfile"
}
}
}
target.entitlements
權利是構建過程執行所需的許可權。
目前支援的權利有
network.host
:允許構建使用訪問主機網路的命令。在 Dockerfile 中,使用RUN --network=host
來執行啟用主機網路的命令。security.insecure
:允許構建在不受預設安全沙盒限制的特權容器中執行命令。此類容器可能會訪問和修改系統資源。在 Dockerfile 中,使用RUN --security=insecure
在特權容器中執行命令。
target "integration-tests" {
# this target requires privileged containers to run nested containers
entitlements = ["security.insecure"]
}
權利透過兩步過程啟用。首先,目標必須宣告其所需的權利。其次,在呼叫 bake
命令時,使用者必須透過傳遞 --allow
標誌或在互動式終端中提示時確認權利來授予權利。這是為了確保使用者瞭解他們授予構建過程的可能不安全的許可權。
target.extra-hosts
使用 extra-hosts
屬性為目標定義自定義主機到 IP 對映。這與向構建命令傳遞 --add-host
標誌具有相同的效果。
target "default" {
extra-hosts = {
my_hostname = "8.8.8.8"
}
}
target.inherits
目標可以從其他目標繼承屬性。使用 inherits
從一個目標引用另一個目標。
在以下示例中,app-dev
目標指定了一個映象名稱和標籤。app-release
目標使用 inherits
重用標籤名稱。
variable "TAG" {
default = "latest"
}
target "app-dev" {
tags = ["docker.io/username/myapp:${TAG}"]
}
target "app-release" {
inherits = ["app-dev"]
platforms = ["linux/amd64", "linux/arm64"]
}
inherits
屬性是一個列表,這意味著您可以從多個其他目標重用屬性。在以下示例中,app-release
目標重用了 app-dev
和 _release
目標的屬性。
target "app-dev" {
args = {
GO_VERSION = "1.20"
BUILDX_EXPERIMENTAL = 1
}
tags = ["docker.io/username/myapp"]
dockerfile = "app.Dockerfile"
labels = {
"org.opencontainers.image.source" = "https://github.com/username/myapp"
}
}
target "_release" {
args = {
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
BUILDX_EXPERIMENTAL = 0
}
}
target "app-release" {
inherits = ["app-dev", "_release"]
platforms = ["linux/amd64", "linux/arm64"]
}
當從多個目標繼承屬性且存在衝突時,inherits
列表中最後出現的目標具有優先權。上一個示例為 app-release
目標兩次定義了 BUILDX_EXPERIMENTAL
引數。它解析為 0
,因為 _release
目標在繼承鏈中最後出現
$ docker buildx bake --print app-release
[+] Building 0.0s (0/0)
{
"group": {
"default": {
"targets": [
"app-release"
]
}
},
"target": {
"app-release": {
"context": ".",
"dockerfile": "app.Dockerfile",
"args": {
"BUILDKIT_CONTEXT_KEEP_GIT_DIR": "1",
"BUILDX_EXPERIMENTAL": "0",
"GO_VERSION": "1.20"
},
"labels": {
"org.opencontainers.image.source": "https://github.com/username/myapp"
},
"tags": [
"docker.io/username/myapp"
],
"platforms": [
"linux/amd64",
"linux/arm64"
]
}
}
}
target.labels
將映象標籤分配給構建。這與 docker build
的 --label
標誌相同。
target "default" {
labels = {
"org.opencontainers.image.source" = "https://github.com/username/myapp"
"com.docker.image.source.entrypoint" = "Dockerfile"
}
}
標籤可以使用 null
值。如果這樣做,構建器將使用 Dockerfile 中指定的標籤值。
target.matrix
矩陣策略允許您根據指定的引數將單個目標分叉成多個不同的變體。這與 [GitHub Actions 的矩陣策略] 的工作方式類似。您可以使用此功能減少 Bake 定義中的重複。
matrix
屬性是從引數名稱到值列表的對映。Bake 將值的每個可能組合構建為一個單獨的目標。
每個生成的 target 必須 具有唯一的名稱。要指定 target 名稱應如何解析,請使用 name
屬性。
以下示例將 app
目標解析為 app-foo
和 app-bar
。它還使用矩陣值來定義 目標構建階段。
target "app" {
name = "app-${tgt}"
matrix = {
tgt = ["foo", "bar"]
}
target = tgt
}
$ docker buildx bake --print app
[+] Building 0.0s (0/0)
{
"group": {
"app": {
"targets": [
"app-foo",
"app-bar"
]
},
"default": {
"targets": [
"app"
]
}
},
"target": {
"app-bar": {
"context": ".",
"dockerfile": "Dockerfile",
"target": "bar"
},
"app-foo": {
"context": ".",
"dockerfile": "Dockerfile",
"target": "foo"
}
}
}
多軸
您可以在矩陣中指定多個鍵,以在多個軸上分叉目標。當使用多個矩陣鍵時,Bake 會構建每個可能的變體。
以下示例構建了四個目標
app-foo-1-0
app-foo-2-0
app-bar-1-0
app-bar-2-0
target "app" {
name = "app-${tgt}-${replace(version, ".", "-")}"
matrix = {
tgt = ["foo", "bar"]
version = ["1.0", "2.0"]
}
target = tgt
args = {
VERSION = version
}
}
每個矩陣目標的多個值
如果您想根據多個值區分矩陣,可以使用對映作為矩陣值。Bake 為每個對映建立一個目標,您可以使用點表示法訪問巢狀值。
以下示例構建了兩個目標
app-foo-1-0
app-bar-2-0
target "app" {
name = "app-${item.tgt}-${replace(item.version, ".", "-")}"
matrix = {
item = [
{
tgt = "foo"
version = "1.0"
},
{
tgt = "bar"
version = "2.0"
}
]
}
target = item.tgt
args = {
VERSION = item.version
}
}
target.name
為使用矩陣策略的目標指定名稱解析。以下示例將 app
目標解析為 app-foo
和 app-bar
。
target "app" {
name = "app-${tgt}"
matrix = {
tgt = ["foo", "bar"]
}
target = tgt
}
target.network
為整個構建請求指定網路模式。這將覆蓋 Dockerfile 中所有 RUN
指令的預設網路模式。接受的值為 default
、host
和 none
。
通常,為構建步驟設定網路模式的更好方法是在 Dockerfile 中使用 RUN --network=
。這樣,您可以為單個構建步驟設定網路模式,並且所有構建 Dockerfile 的人都將獲得一致的行為,而無需向構建命令傳遞額外的標誌。
如果您在 Bake 檔案中將網路模式設定為 host
,則在呼叫 bake
命令時還必須授予 network.host
許可權。這是因為 host
網路模式需要提升的許可權,並且可能存在安全風險。您可以將 --allow=network.host
傳遞給 docker buildx bake
命令以授予許可權,或者如果您使用互動式終端,則可以在提示時確認許可權。
target "app" {
# make sure this build does not access internet
network = "none"
}
target.no-cache-filter
不要對指定階段使用構建快取。這與 docker build
的 --no-cache-filter
標誌相同。以下示例避免對 foo
構建階段使用構建快取。
target "default" {
no-cache-filter = ["foo"]
}
target.no-cache
構建映象時不要使用快取。這與 docker build
的 --no-cache
標誌相同。
target "default" {
no-cache = 1
}
target.output
匯出構建輸出的配置。這與 --output
標誌 相同。以下示例將目標配置為使用僅快取輸出,
target "default" {
output = [{ type = "cacheonly" }]
}
target.platforms
為構建目標設定目標平臺。這與 --platform
標誌 相同。以下示例為三種架構建立了一個多平臺構建。
target "default" {
platforms = ["linux/amd64", "linux/arm64", "linux/arm/v7"]
}
target.pull
配置構建器在構建目標時是否應嘗試拉取映象。這與 docker build
的 --pull
標誌相同。以下示例強制構建器始終拉取構建目標中引用的所有映象。
target "default" {
pull = true
}
target.secret
定義要暴露給構建目標的秘密。這與 --secret
標誌 相同。
variable "HOME" {
default = null
}
target "default" {
secret = [
{
type = "env"
id = "KUBECONFIG"
},
{
type = "file"
id = "aws"
src = "${HOME}/.aws/credentials"
}
]
}
這允許您在 Dockerfile 中 掛載秘密。
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \
aws cloudfront create-invalidation ...
RUN --mount=type=secret,id=KUBECONFIG,env=KUBECONFIG \
helm upgrade --install
target.shm-size
設定使用 RUN
指令時為構建容器分配的共享記憶體大小。
格式為
。number
必須大於 0
。單位是可選的,可以是 b
(位元組)、k
(千位元組)、m
(兆位元組) 或 g
(千兆位元組)。如果省略單位,系統將使用位元組。
這與 docker build
的 --shm-size
標誌相同。
target "default" {
shm-size = "128m"
}
注意在大多數情況下,建議讓構建器自動確定適當的配置。只有當複雜構建場景需要特定的效能調優時,才應考慮手動調整。
target.ssh
定義要暴露給構建的 SSH 代理套接字或金鑰。這與 --ssh
標誌 相同。如果您需要在構建期間訪問私有倉庫,這會很有用。
target "default" {
ssh = [{ id = "default" }]
}
FROM alpine
RUN --mount=type=ssh \
apk add git openssh-client \
&& install -m 0700 -d ~/.ssh \
&& ssh-keyscan github.com >> ~/.ssh/known_hosts \
&& git clone git@github.com:user/my-private-repo.git
target.tags
用於構建目標的映象名稱和標籤。這與 --tag
標誌 相同。
target "default" {
tags = [
"org/repo:latest",
"myregistry.azurecr.io/team/image:v1"
]
}
target.target
設定要構建的目標構建階段。這與 --target
標誌 相同。
target "default" {
target = "binaries"
}
target.ulimits
Ulimits 會覆蓋使用 RUN
指令時構建容器的預設 ulimits,並以軟限制和硬限制指定,例如:
,例如
target "app" {
ulimits = [
"nofile=1024:1024"
]
}
注意如果您未提供
hard limit
,則soft limit
將用於這兩個值。如果未設定ulimits
,它們將從守護程序上設定的預設ulimits
繼承。
注意在大多數情況下,建議讓構建器自動確定適當的配置。只有當複雜構建場景需要特定的效能調優時,才應考慮手動調整。
組
組允許您一次呼叫多個構建(目標)。
group "default" {
targets = ["db", "webapp-dev"]
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
}
target "db" {
dockerfile = "Dockerfile.db"
tags = ["docker.io/username/db"]
}
如果組和目標都存在且名稱相同,則組優先。以下 bake 檔案構建 default
組。Bake 忽略 default
目標。
target "default" {
dockerfile-inline = "FROM ubuntu"
}
group "default" {
targets = ["alpine", "debian"]
}
target "alpine" {
dockerfile-inline = "FROM alpine"
}
target "debian" {
dockerfile-inline = "FROM debian"
}
變數
HCL 檔案格式支援變數塊定義。您可以將變數用作 Dockerfile 中的構建引數,或將它們插入到 Bake 檔案中的屬性值中。
variable "TAG" {
type = string
default = "latest"
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:${TAG}"]
}
您可以在 Bake 檔案中為變數分配預設值,或為其分配 null
值。如果您分配 null
值,Buildx 將使用 Dockerfile 中的預設值。
您可以使用環境變數覆蓋 Bake 檔案中設定的變數預設值。以下示例將 TAG
變數設定為 dev
,覆蓋上一個示例中顯示的預設 latest
值。
$ TAG=dev docker buildx bake webapp-dev
變數也可以被賦予顯式型別。如果提供了型別,它將用於驗證預設值(如果已設定)以及任何覆蓋。這在使用旨在被覆蓋的複雜型別時特別有用。前面的示例可以擴充套件以應用任意系列的標籤。
variable "TAGS" {
default = ["latest"]
type = list(string)
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = [for tag in TAGS: "docker.io/username/webapp:${tag}"]
}
此示例展示瞭如何在不更改檔案或使用自定義函式/解析的情況下生成三個標籤
$ TAGS=dev,latest,2 docker buildx bake webapp-dev
變數型別
以下原始型別可用
字串
數字
布林
型別以關鍵字形式表達;它必須以字面量形式表達
variable "OK" {
type = string
}
# cannot be an actual string
variable "BAD" {
type = "string"
}
# cannot be the result of an expression
variable "ALSO_BAD" {
type = lower("string")
}
指定原始型別對於表明意圖(尤其是在未提供預設值時)可能很有價值,但通常情況下,即使沒有顯式型別,Bake 的行為也會如預期。
複雜型別使用“型別建構函式”表達;它們是
tuple([
,...]) list(
) set(
) map(
) object({
= },...})
以下是這些示例,以及如何表達(可選)預設值
# structured way to express "1.2.3-alpha"
variable "MY_VERSION" {
type = tuple([number, number, number, string])
default = [1, 2, 3, "alpha"]
}
# JDK versions used in a matrix build
variable "JDK_VERSIONS" {
type = list(number)
default = [11, 17, 21]
}
# better way to express the previous example; this will also
# enforce set semantics and allow use of set-based functions
variable "JDK_VERSIONS" {
type = set(number)
default = [11, 17, 21]
}
# with the help of lookup(), translate a 'feature' to a tag
variable "FEATURE_TO_NAME" {
type = map(string)
default = {featureA = "slim", featureB = "tiny"}
}
# map a branch name to a registry location
variable "PUSH_DESTINATION" {
type = object({branch = string, registry = string})
default = {branch = "main", registry = "prod-registry.invalid.com"}
}
# make the previous example more useful with composition
variable "PUSH_DESTINATIONS" {
type = list(object({branch = string, registry = string}))
default = [
{branch = "develop", registry = "test-registry.invalid.com"},
{branch = "main", registry = "prod-registry.invalid.com"},
]
}
請注意,在每個示例中,即使不存在型別,預設值也是有效的。如果省略型別,前三個都將被視為 tuple
;您將受限於對 tuple
操作的函式,例如,無法新增元素。類似地,第三個和第四個都將被視為 object
,具有該型別的限制和語義。簡而言之,在沒有型別的情況下,任何用 []
分隔的值都是 tuple
,任何用 {}
分隔的值都是 object
。複雜型別的顯式型別不僅提供了使用適用於該專門型別的功能的能力,而且還是提供覆蓋的先決條件。
注意有關更多詳細資訊,請參閱 HCL 型別表示式 頁面。
覆蓋變數
正如 變數介紹 中所述,原始型別(string
、number
和 bool
)可以在沒有型別的情況下被覆蓋,並且通常會按預期工作。(當未提供顯式型別時,如果預設值缺少 {}
或 []
分隔符,則變數被假定為原始型別;既沒有型別也沒有預設值的變數被視為 string
。)當然,這些相同的覆蓋也可以與顯式型別一起使用;它們可能有助於處理您希望 VAR=true
是 string
的邊緣情況,而在沒有型別的情況下,它可能是 string
或 bool
,具體取決於其使用方式/位置。複雜型別的變數只能在提供型別時被覆蓋。這仍然透過環境變數完成,但值可以透過 CSV 或 JSON 提供。
CSV 覆蓋
這被認為是規範方法,非常適合互動式使用。假設 list
和 set
將是最常見的複雜型別,也是最常見的旨在被覆蓋的複雜型別。因此,list
和 set
(以及 tuple
;儘管被視為結構型別,但在這方面它更像集合型別)具有完整的 CSV 支援。
對 map
和 object
的支援有限,不支援複合型別;對於這些高階情況,可以使用 使用 JSON 的替代機制。
JSON 覆蓋
覆蓋也可以透過 JSON 提供。這是提供某些複雜型別的唯一可用方法,如果覆蓋已經是 JSON(例如,如果它們來自 JSON API),則可能很方便。當處理難以或不可能使用 CSV 指定的值(例如,包含引號或逗號的值)時,也可以使用它。要使用 JSON,只需在變數名稱後附加 _JSON
。在此人為設計的示例中,CSV 無法處理第二個值;儘管是支援的 CSV 型別,但必須使用 JSON
variable "VALS" {
type = list(string)
default = ["some", "list"]
}
$ cat data.json
["hello","with,comma","with\"quote"]
$ VALS_JSON=$(< data.json) docker buildx bake
# CSV equivalent, though the second value cannot be expressed at all
$ VALS='hello,"with""quote"' docker buildx bake
此示例說明了一些優先規則和使用規則
variable "FOO" {
type = string
default = "foo"
}
variable "FOO_JSON" {
type = string
default = "foo"
}
變數 FOO
只能使用 CSV 覆蓋,因為通常用於 JSON 覆蓋的 FOO_JSON
已經是一個定義的變數。由於 FOO_JSON
是一個實際變數,因此設定該環境變數將預期為 CSV 值。對於此變數,JSON 覆蓋是可能的,使用環境變數 FOO_JSON_JSON
。
# These three are all equivalent, setting variable FOO=bar
$ FOO=bar docker buildx bake <...>
$ FOO='bar' docker buildx bake <...>
$ FOO="bar" docker buildx bake <...>
# Sets *only* variable FOO_JSON; FOO is untouched
$ FOO_JSON=bar docker buildx bake <...>
# This also sets FOO_JSON, but will fail due to not being valid JSON
$ FOO_JSON_JSON=bar docker buildx bake <...>
# These are all equivalent
$ cat data.json
"bar"
$ FOO_JSON_JSON=$(< data.json) docker buildx bake <...>
$ FOO_JSON_JSON='"bar"' docker buildx bake <...>
$ FOO_JSON=bar docker buildx bake <...>
# This results in setting two different variables, both specified as CSV (FOO=bar and FOO_JSON="baz")
$ FOO=bar FOO_JSON='"baz"' docker buildx bake <...>
# These refer to the same variable with FOO_JSON_JSON having precedence and read as JSON (FOO_JSON=baz)
$ FOO_JSON=bar FOO_JSON_JSON='"baz"' docker buildx bake <...>
內建變數
以下變數是內建變數,您可以在 Bake 中使用它們而無需定義它們。
變數 | 描述 |
---|---|
BAKE_CMD_CONTEXT | 在使用遠端 Bake 檔案構建時,儲存主上下文。 |
BAKE_LOCAL_PLATFORM | 返回當前平臺的預設平臺規範(例如 linux/amd64 )。 |
使用環境變數作為預設值
您可以將 Bake 變數設定為使用環境變數的值作為預設值
variable "HOME" {
default = "$HOME"
}
將變數插入屬性中
要將變數插入屬性字串值中,您必須使用大括號。以下程式碼不起作用
variable "HOME" {
default = "$HOME"
}
target "default" {
ssh = ["default=$HOME/.ssh/id_rsa"]
}
將變數用大括號括起來,您想插入它的地方
variable "HOME" {
default = "$HOME"
}
target "default" {
- ssh = ["default=$HOME/.ssh/id_rsa"]
+ ssh = ["default=${HOME}/.ssh/id_rsa"]
}
在將變數插入屬性之前,您必須先在 bake 檔案中宣告它,如以下示例所示。
$ cat docker-bake.hcl
target "default" {
dockerfile-inline = "FROM ${BASE_IMAGE}"
}
$ docker buildx bake
[+] Building 0.0s (0/0)
docker-bake.hcl:2
--------------------
1 | target "default" {
2 | >>> dockerfile-inline = "FROM ${BASE_IMAGE}"
3 | }
4 |
--------------------
ERROR: docker-bake.hcl:2,31-41: Unknown variable; There is no variable named "BASE_IMAGE"., and 1 other diagnostic(s)
$ cat >> docker-bake.hcl
variable "BASE_IMAGE" {
default = "alpine"
}
$ docker buildx bake
[+] Building 0.6s (5/5) FINISHED
函式
# docker-bake.hcl
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
args = {
buildno = "${add(123, 1)}"
}
}
此外,還支援 使用者定義函式
# docker-bake.hcl
function "increment" {
params = [number]
result = number + 1
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
args = {
buildno = "${increment(123)}"
}
}
注意有關更多詳細資訊,請參閱 使用者定義 HCL 函式 頁面。