使用 Bake 与附加上下文

除定义构建上下文的主要 context 键外,每个目标还可以使用带有键 contexts 的映射来定义其他命名上下文。这些值映射到 构建命令 中的 --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