Bake 檔案參考

Bake 檔案是用來定義您透過 docker buildx bake 執行的工作流程的檔案。

檔案格式

您可以透過以下檔案格式定義您的 Bake 檔案:

  • HashiCorp 配置語言 (HCL)
  • JSON
  • YAML (Compose 檔案)

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

您可以透過使用 --file 旗標明確指定檔案位置

$ docker buildx bake --file ../docker/bake.hcl --print

如果您未明確指定檔案,Bake 會在目前的工作目錄中尋找該檔案。如果找到多個 Bake 檔案,所有檔案將合併為單一定義。檔案會根據查找順序進行合併。這表示如果您的專案同時包含 compose.yaml 檔案和 docker-bake.hcl 檔案,Bake 會先載入 compose.yaml 檔案,然後再載入 docker-bake.hcl 檔案。

如果合併的檔案包含重複的特性定義,則這些定義將根據特性,由最後出現的定義進行合併或覆寫。以下特性將被最後出現的定義覆寫:

  • 目標.cache-to
  • 目標.dockerfile-inline
  • 目標.dockerfile
  • 目標.outputs
  • 目標.platforms
  • 目標.pull
  • 目標.tags
  • 目標.target

例如,如果 compose.yamldocker-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.yamldocker-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"
}

下表顯示了您可以指派給目標的完整特性列表:

名稱類型描述
argsMap建置參數
annotationsList匯出器註釋
attestList建置證明
cache-fromList外部快取來源
cache-toList外部快取目的地
callString指定要為目標呼叫的前端方法。
contextString位於指定路徑或 URL 中的檔案集合
contextsMap額外建置情境
descriptionString目標描述
dockerfile-inlineString內嵌 Dockerfile 字串
dockerfileStringDockerfile 位置
entitlementsList建置過程執行所需的權限
extra-hostsList自訂主機到 IP 映射
inheritsList從其他目標繼承特性
labelsMap映像檔中繼資料
matrixMap定義一組變數,將一個目標分叉為多個目標。
nameString使用矩陣時覆寫目標名稱。
no-cache-filterList停用特定階段的建置快取
no-cache布林值完全停用建置快取
outputList輸出目的地
platformsList目標平台
pull布林值總是拉取映像檔
secretList要公開給建置的機密
shm-sizeList/dev/shm 的大小
sshList要公開給建置的 SSH 代理伺服器通訊端或金鑰
tagsList映像檔名稱和標籤
targetString目標建置階段
ulimitsListUlimit 選項

目標.args

使用 args 特性來為目標定義建置參數。這與向建置指令傳遞 --build-arg 旗標具有相同的效果。

target "default" {
  args = {
    VERSION = "0.0.0+unknown"
  }
}

您可以將 args 特性設定為使用 null 值。這樣會強制目標使用 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"]
}

目標.annotations

annotations 特性允許您為使用 bake 建置的映像檔添加註釋。該鍵接受一個註釋列表,格式為 KEY=VALUE

target "default" {
  output = [{ type = "image", name = "foo" }]
  annotations = ["org.opencontainers.image.authors=dvdksn"]
}

預設情況下,註釋會添加到映像檔 manifest 中。您可以透過在註釋中添加前綴來配置註釋的層級,該前綴包含您要註釋的所有層級的逗號分隔列表。以下範例為映像檔索引和 manifest 添加了註釋。

target "default" {
  output = [
    {
      type = "image"
      name = "foo"
    }
  ]
  annotations = ["index,manifest:org.opencontainers.image.authors=dvdksn"]
}

請閱讀「指定註釋層級」以了解支援的層級。

目標.attest

attest 特性允許您將 建置證明應用於目標。此特性接受證明參數的長格式 CSV 版本。

target "default" {
  attest = [
    {
      type = "provenance"
      mode = "max"
    },
    {
      type = "sbom"
    }
  ]
}

目標.cache-from

建置快取來源。建置器會從您指定的位置匯入快取。它使用 Buildx 快取儲存後端,其運作方式與 --cache-from 旗標相同。這接受一個列表值,因此您可以指定多個快取來源。

target "app" {
  cache-from = [
    {
      type = "s3"
      region = "eu-west-1"
      bucket = "mybucket"
    },
    {
      type = "registry"
      ref = "user/repo:cache"
    }
  ]
}

目標.cache-to

建置快取匯出目的地。建置器會將其建置快取匯出到您指定的位置。它使用 Buildx 快取儲存後端,其運作方式與 --cache-to 旗標相同。這接受一個列表值,因此您可以指定多個快取匯出目標。

target "app" {
  cache-to = [
    {
      type = "s3"
      region = "eu-west-1"
      bucket = "mybucket"
    },
    {
      type = "inline"
    }
  ]
}

目標.call

指定要使用的前端方法。前端方法讓您可以,例如,僅執行建置檢查,而不是執行建置。這與 --call 旗標相同。

target "app" {
  call = "check"
}

支援的值為:

  • build 建置目標 (預設值)
  • check:評估目標的建置檢查
  • outline:顯示目標的建置參數及其預設值 (如果可用)
  • targets:列出載入定義中的所有 Bake 目標,以及其描述

有關前端方法的更多資訊,請參閱 docker buildx build --call 的 CLI 參考。

目標.context

指定此目標使用的建置情境位置。接受 URL 或目錄路徑。這與您傳遞給建置指令的建置情境位置參數相同。

target "app" {
  context = "./src/www"
}

預設情況下,這會解析為目前工作目錄 (".")。

$ docker buildx bake --print -f - <<< 'target "default" {}'
[+] Building 0.0s (0/0)
{
  "target": {
    "default": {
      "context": ".",
      "dockerfile": "Dockerfile"
    }
  }
}

目標.contexts

額外建置情境。這與 --build-context 旗標相同。此特性接受一個映射 (map),其中鍵會產生您可以在建置中引用的命名情境。

您可以指定不同類型的情境,例如本地目錄、Git URL,甚至其他 Bake 目標。Bake 會根據情境值的模式自動判斷情境的類型。

情境類型範例
容器映像檔docker-image://alpine@sha256:0123456789
Git URLhttps://github.com/user/proj.git
HTTP URLhttps://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"

目標.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 檔案中可用的建置目標時提供更具資訊的輸出。

目標.dockerfile-inline

使用字串值作為建置目標的內嵌 Dockerfile。

target "default" {
  dockerfile-inline = "FROM alpine\nENTRYPOINT [\"echo\", \"hello\"]"
}

dockerfile-inline 優先於 dockerfile 特性。如果您同時指定兩者,Bake 會使用內嵌版本。

目標.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"
    }
  }
}

目標.entitlements

授權 (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 旗標或在互動式終端機中提示時確認授權來授予授權。這是為了確保使用者了解他們授予建置過程的可能不安全的權限。

目標.extra-hosts

使用 extra-hosts 特性為目標定義自訂主機到 IP 映射。這與向建置指令傳遞 --add-host 旗標具有相同的效果。

target "default" {
  extra-hosts = {
    my_hostname = "8.8.8.8"
  }
}

目標.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"
      ]
    }
  }
}

目標.labels

將映像檔標籤指派給建置。這與 docker build--label 旗標相同。

target "default" {
  labels = {
    "org.opencontainers.image.source" = "https://github.com/username/myapp"
    "com.docker.image.source.entrypoint" = "Dockerfile"
  }
}

標籤可以使用 null 值。如果您這樣做,建置器將使用 Dockerfile 中指定的標籤值。

目標.matrix

矩陣策略允許您根據指定的參數,將單一目標分叉為多個不同的變體。這與 [GitHub Actions 的矩陣策略] 類似。您可以使用此功能來減少 bake 定義中的重複。

matrix 特性是一個將參數名稱映射到值列表的映射 (map)。Bake 會將值的每個可能組合建置為一個單獨的目標。

每個生成的目標 **必須** 具有唯一的名稱。若要指定目標名稱應如何解析,請使用 name 特性。

以下範例將 app 目標解析為 app-fooapp-bar。它還使用矩陣值來定義[目標建置階段](#targettarget)。

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
  }
}

每個矩陣目標的多個值

如果您想在單一值之外區分矩陣,可以使用映射 (map) 作為矩陣值。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
  }
}

目標.name

指定使用矩陣策略的目標的名稱解析。以下範例將 app 目標解析為 app-fooapp-bar

target "app" {
  name = "app-${tgt}"
  matrix = {
    tgt = ["foo", "bar"]
  }
  target = tgt
}

目標.network

指定整個建置請求的網路模式。這將覆寫 Dockerfile 中所有 RUN 指令的預設網路模式。接受的值為 defaulthostnone

通常,為您的建置步驟設定網路模式的更好方法是在 Dockerfile 中使用 RUN --network=<value>。這樣,您可以為個別建置步驟設定網路模式,並且每個建置 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"
}

目標.no-cache-filter

不要對指定的階段使用建置快取。這與 docker build--no-cache-filter 旗標相同。以下範例避免對 foo 建置階段使用建置快取。

target "default" {
  no-cache-filter = ["foo"]
}

目標.no-cache

建置映像檔時不要使用快取。這與 docker build--no-cache 旗標相同。

target "default" {
  no-cache = 1
}

目標.output

匯出建置輸出的配置。這與 --output 旗標相同。以下範例將目標配置為使用僅快取輸出,

target "default" {
  output = [{ type = "cacheonly" }]
}

目標.platforms

為建置目標設定目標平台。這與 --platform 旗標相同。以下範例為三種架構建立了多平台建置。

target "default" {
  platforms = ["linux/amd64", "linux/arm64", "linux/arm/v7"]
}

目標.pull

配置建置器在建置目標時是否應嘗試拉取映像檔。這與 docker build--pull 旗標相同。以下範例強制建置器始終拉取建置目標中引用的所有映像檔。

target "default" {
  pull = true
}

目標.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

目標.shm-size

設定使用 RUN 指令時為建置容器分配的共用記憶體大小。

格式為 <數字><單位>數字必須大於 0。單位是可選的,可以是 b (位元組)、k (千位元組)、m (百萬位元組) 或 g (十億位元組)。如果您省略單位,系統會使用位元組。

這與 docker build--shm-size 旗標相同。

target "default" {
  shm-size = "128m"
}
注意

在大多數情況下,建議讓建置器自動決定適當的配置。僅當複雜建置情境需要特定的效能調優時,才應考慮手動調整。

目標.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

目標.tags

用於建置目標的映像檔名稱和標籤。這與 --tag 旗標相同。

target "default" {
  tags = [
    "org/repo:latest",
    "myregistry.azurecr.io/team/image:v1"
  ]
}

目標.target

設定要建置的目標建置階段。這與 --target 旗標相同。

target "default" {
  target = "binaries"
}

目標.ulimits

當使用 RUN 指令時,Ulimits 會覆寫建置容器的預設 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

變數類型

以下基本類型可用:

  • string
  • number
  • bool

類型表示為關鍵字;它必須表示為字面值。

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([<type>,...])
  • list(<type>)
  • set(<type>)
  • map(<type>)
  • object({<attr>=<type>},...})

以下是每個類型的範例,以及 (可選的) 預設值將如何表示:

# 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 類型表達式頁面以獲取更多詳細資訊。

覆寫變數

變數介紹中所述,基本類型 (stringnumberbool) 可以在沒有類型設定的情況下被覆寫,並且通常會按預期運作。(當未提供明確類型設定時,如果預設值缺少 {}[] 界定符,則變數被假定為基本類型;如果既沒有類型設定也沒有預設值,則變數被視為 string。) 當然,這些相同的覆寫也可以與明確類型設定一起使用;它們可能在您希望 VAR=truestring 的邊緣情況下有所幫助,而在沒有類型設定的情況下,它可能是 stringbool,具體取決於其使用方式/位置。使用複雜類型覆寫變數只能在提供類型時完成。這仍然透過環境變數完成,但值可以透過 CSV 或 JSON 提供。

CSV 覆寫

這被認為是規範方法,非常適合互動式使用。假設 listset 將是最常見的複雜類型,也是最常見的旨在被覆寫的複雜類型。因此,listset (以及 tuple;儘管被認為是結構類型,但在這方面它更像是一種集合類型) 獲得了完整的 CSV 支援。

mapobject 的支援有限,並且不支援複合類型;對於這些進階情況,可以使用使用 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

函數

go-cty 提供的一組通用函數可在 HCL 檔案中使用。

# 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 函數頁面以獲取更多詳細資訊。

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.