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 檔案。

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

  • target.cache-to
  • target.dockerfile-inline
  • target.dockerfile
  • target.outputs
  • target.platforms
  • target.pull
  • target.tags
  • target.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"
}

下表顯示了您可以分配給目標的完整屬性列表

名稱型別描述
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"
}

支援的值有

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

有關前端方法的更多資訊,請參閱 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 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"

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-fooapp-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-fooapp-bar

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

target.network

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

通常,為構建步驟設定網路模式的更好方法是在 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 型別表示式 頁面。

覆蓋變數

正如 變數介紹 中所述,原始型別(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

函式

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

# 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 函式 頁面。