使用 Bake 附加上下文

除了定义构建上下文的主 `context` 键外,每个目标还可以使用 `contexts` 键定义的映射来定义额外的命名上下文。这些值映射到 build 命令 中的 `--build-context` 标志。

在 Dockerfile 中,这些上下文可以通过 `FROM` 指令或 `--from` 标志使用。

支持的上下文值为

  • 本地文件系统目录
  • 容器镜像
  • Git URL
  • HTTP URL
  • Bake 文件中另一个目标的名称

固定 Alpine 镜像

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

使用辅助源目录

Dockerfile
FROM golang
COPY --from=src . .
docker-bake.hcl
# Running `docker buildx bake app` will result in `src` not pointing
# to some previous build stage but to the client filesystem, not part of the context.
target "app" {
  contexts = {
    src = "../path/to/source"
  }
}

将目标用作构建上下文

要将一个目标的结果用作另一个目标的构建上下文,请使用 `target:` 前缀指定目标名称。

baseapp.Dockerfile
FROM scratch
Dockerfile
# 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 文件,它定义了以下目标组

docker-bake.hcl
group "default" {
  targets = ["target1", "target2"]
}

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

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

在这种情况下,当您构建默认组时,上下文 `.` 会传输两次:一次用于 `target1`,一次用于 `target2`。

如果您的上下文很小,并且您使用的是本地构建器,重复的上下文传输可能不是什么大问题。但是,如果您的构建上下文很大,或者您有大量目标,或者您通过网络将上下文传输到远程构建器,上下文传输就会成为性能瓶颈。

为了避免多次传输相同的上下文,您可以定义一个只加载上下文文件的命名上下文,并让需要这些文件的每个目标引用该命名上下文。例如,以下 Bake 文件定义了一个名为 `ctx` 的命名目标,`target1` 和 `target2` 都使用它

docker-bake.hcl
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` 挂载其文件。

Dockerfile
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
© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.