将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