使用 Bake 與額外環境

除了定義建置環境的主要 `context` 鍵之外,每個目標還可以透過使用鍵 `contexts` 定義的地圖來定義額外的命名環境。這些值會對應到 build 命令 中的 `--build-context` 旗標。

在 Dockerfile 內,可以使用 `FROM` 指令或 `--from` 旗標來使用這些環境。

支援的環境值為

  • 本機檔案系統目錄
  • 容器映像檔
  • Git URL
  • HTTP URL
  • Bake 檔案中另一個目標的名稱

釘選 alpine 映像檔

# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello world"
# docker-bake.hcl
target "app" {
  contexts = {
    alpine = "docker-image://alpine:3.13"
  }
}

使用次要來源目錄

# syntax=docker/dockerfile:1
FROM scratch AS src

FROM golang
COPY --from=src . .
# docker-bake.hcl
target "app" {
  contexts = {
    src = "../path/to/source"
  }
}

使用目標作為建置環境

要將一個目標的結果用作另一個目標的建置環境,請使用 `target:` 前綴指定目標名稱。

# syntax=docker/dockerfile:1
FROM baseapp
RUN echo "Hello world"
# docker-bake.hcl
target "base" {
  dockerfile = "baseapp.Dockerfile"
}

target "app" {
  contexts = {
    baseapp = "target:base"
  }
}

在大多數情況下,您應該只使用一個具有多個目標的多階段 Dockerfile 來獲得類似的行為。僅當您有多個無法輕易合併成一個的 Dockerfile 時,才建議使用此案例。

重複資料刪除環境傳輸

**注意**

從 Buildx 0.17.0 版開始,Bake 會自動為共用相同環境的目標刪除重複的環境傳輸。除了 Buildx 0.17.0 版之外,建置器必須執行 BuildKit 0.16.0 版或更新版本,且 Dockerfile 語法必須為 `docker/dockerfile:1.10` 或更新版本。

如果您符合這些要求,則不需要如本節所述手動刪除重複的環境傳輸。

  • 要檢查您的 Buildx 版本,請執行 `docker buildx version`。
  • 要檢查您的 BuildKit 版本,請執行 `docker buildx inspect --bootstrap` 並尋找 `BuildKit version` 欄位。
  • 要檢查您的 Dockerfile 語法版本,請檢查 Dockerfile 中的 `syntax` 剖析器指令。如果不存在,則預設版本為您目前 BuildKit 版本隨附的任何版本。要明確設定版本,請在 Dockerfile 的頂端新增 `#syntax=docker/dockerfile:1.10`。

當您同時建置目標時,使用群組,會針對每個目標獨立載入建置環境。如果群組中的多個目標使用相同的環境,則每次使用該環境時都會傳輸一次。這可能會對建置時間造成顯著影響,具體取決於您的建置設定。例如,假設您有一個定義下列目標群組的 Bake 檔案

group "default" {
  targets = ["target1", "target2"]
}

target "target1" {
  target = "target1"
  context = "."
}

target "target2" {
  target = "target2"
  context = "."
}

在此情況下,當您建置預設群組時,環境 `.` 會傳輸兩次:一次用於 `target1`,一次用於 `target2`。

如果您的環境很小,而且您使用的是本機建置器,則重複的環境傳輸可能不是什麼大問題。但是,如果您的建置環境很大,或者您有大量的目標,或者您正在透過網路將環境傳輸到遠端建置器,則環境傳輸會成為效能瓶頸。

為了避免多次傳輸相同的上下文,您可以定義一個僅載入上下文檔案的命名上下文,並讓每個需要這些檔案的目標參考該命名上下文。例如,以下 Bake 檔案定義了一個名為 ctx 的命名目標,它被 target1target2 使用。

group "default" {
  targets = ["target1", "target2"]
}

target "ctx" {
  context = "."
  target = "ctx"
}

target "target1" {
  target = "target1"
  contexts = {
    ctx = "target:ctx"
  }
}

target "target2" {
  target = "target2"
  contexts = {
    ctx = "target:ctx"
  }
}

命名上下文 ctx 代表一個 Dockerfile 階段,它會從其上下文 (.) 複製檔案。Dockerfile 中的其他階段現在可以參考 ctx 命名上下文,例如,使用 --mount=from=ctx 掛載其檔案。

FROM scratch AS ctx
COPY --link . .

FROM golang:alpine AS target1
WORKDIR /work
RUN --mount=from=ctx \
    go build -o /out/client ./cmd/client \

FROM golang:alpine AS target2
WORKDIR /work
RUN --mount=from=ctx \
    go build -o /out/server ./cmd/server