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.override.json
  7. docker-bake.hcl
  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.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 表示法中,屬性是物件,而屬性是賦予這些物件的值。

以下範例顯示了 HCL 格式的相同 Bake 檔案

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清單外部快取目的地
context字串位於指定路徑或 URL 中的檔案集
contexts映射其他建置上下文
dockerfile-inline字串內嵌 Dockerfile 字串
dockerfile字串Dockerfile 位置
inherits清單繼承自其他目標的屬性
labels映射映像檔的後設資料
matrix映射定義一組將目標分支成多個目標的變數。
name字串使用矩陣時覆寫目標名稱。
no-cache-filter清單停用特定階段的建置快取
no-cache布林值完全停用建置快取
output清單輸出目的地
platforms清單目標平台
pull布林值永遠提取映像檔
secret清單要公開給建置的機密
shm-size清單`/dev/shm` 的大小
ssh清單要公開給建置的 SSH 代理程式通訊端或金鑰
tags清單映像檔名稱與標籤
目標字串目標建置階段
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,annotation.org.opencontainers.image.authors=dvdksn"]
}

預設情況下,註釋會新增到映像檔資訊清單。您可以透過在註釋前加上前綴來設定註釋的層級,前綴包含以逗號分隔的所有要註釋的層級清單。以下範例將註釋新增到映像檔索引和資訊清單。

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

指定註釋層級 中閱讀關於支援的層級。

target.attest

attest 屬性可讓您將 建置證明

target.cache-from

建置快取來源。建置器會從您指定的位置匯入快取。它使用 Buildx 快取儲存後端--cache-from

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 --calltarget.context

指定用於此目標的建置上下文位置。接受 URL 或目錄路徑。這與傳遞給建置指令的 建置上下文

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

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

target.contexts

其他建置上下文。這與 --build-context 旗標

上下文類型範例
容器映像檔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.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

權限是建置流程執行所需的權限。

目前支援的權限有

target "integration-tests" {
  # this target requires privileged containers to run nested containers
  entitlements = ["security.insecure"]
}

權限啟用分為兩個步驟。首先,目標必須聲明其所需的權限。其次,在呼叫 bake 命令時,使用者必須透過傳遞 --allow 旗標或在互動式終端機中確認權限來授予權限。這是為了確保使用者知道他們授予建置流程的可能不安全權限。

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 將每個可能的值組合建置為一個單獨的目標。

每個生成的目標**必須**具有唯一的名稱。要指定目標名稱應如何解析,請使用 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 會建置每個可能的變體。

以下範例建置四個目標

target "app" {
  name = "app-${tgt}-${replace(version, ".", "-")}"
  matrix = {
    tgt = ["foo", "bar"]
    version = ["1.0", "2.0"]
  }
  target = tgt
  args = {
    VERSION = version
  }
}

每個矩陣目標的多個值

如果您想區分矩陣中的多個值,可以使用映射作為矩陣值。 Bake 會為每個映射創建一個目標,您可以使用點表示法訪問嵌套值。

以下範例建置兩個目標

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

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

定義要公開給建置目標的 secrets。這與 --secret 旗標

variable "HOME" {
  default = null
}

target "default" {
  secret = [
    "type=env,id=KUBECONFIG",
    "type=file,id=aws,src=${HOME}/.aws/credentials"
  ]
}

這讓您可以在 Dockerfile 中掛載 secret

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 指令時,為建置容器分配的共享記憶體大小。

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

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

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

注意事項

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

target.ssh

定義要公開給建置的 SSH 代理程式通訊端或金鑰。這與 --ssh 旗標

target "default" {
  ssh = ["default"]
}

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

注意事項

如果您未提供 硬限制,則 軟限制 將用於兩個值。如果未設定任何 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" {
  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

內建變數

以下變數是內建變數,您可以在 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 函數 頁面。