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.yamldocker-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.yamldocker-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列表外部缓存目标
contextstring位于指定路径或 URL 中的一组文件
contexts地图附加构建上下文
dockerfile-inlinestring内联 Dockerfile 字符串
dockerfilestringDockerfile 位置
inherits列表从其他目标继承属性
labels地图镜像元数据
matrix地图定义一组变量,将目标拆分为多个目标。
namestring在使用矩阵时覆盖目标名称。
no-cache-filter列表为特定阶段禁用构建缓存
no-cache布尔值完全禁用构建缓存
output列表输出目的地
platforms列表目标平台
pull布尔值始终拉取镜像
secret列表暴露给构建的密钥
shm-size列表大小为 /dev/shm
ssh列表暴露给构建的SSH代理套接字或密钥
tags列表镜像名称和标签
targetstring目标构建阶段
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 属性允许您将 构建证明 应用到目标上。 此属性接受证明参数的长格式 CSV 版本。

target "default" {
  attest = [
    "type=provenance,mode=min",
    "type=sbom"
  ]
}

target.cache-from

构建缓存来源。 构建器从您指定的位置导入缓存。 它使用 Buildx 缓存存储后端, 其工作方式与 --cache-from 标志相同。 这是一个列表值,因此您可以指定多个缓存来源。

target "app" {
  cache-from = [
    "type=s3,region=eu-west-1,bucket=mybucket",
    "user/repo:cache",
  ]
}

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

有关前端方法的更多信息,请参阅 CLI 参考中的 docker buildx build --call

target.context

指定用于此目标的构建上下文的位置。 接受 URL 或目录路径。 这与传递给构建命令的 构建上下文 位置参数相同。

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

这默认解析为当前工作目录(".")。

$ docker buildx bake --print -f - <<< 'target "default" {}'
[+] Building 0.0s (0/0)
{
  "target": {
    "default": {
      "context": ".",
      "dockerfile": "Dockerfile"
    }
  }
}

target.contexts

附加构建上下文。 这与 --build-context 标志。 此属性采用映射,其中键生成命名上下文,您可以在构建中引用这些上下文。

您可以指定不同类型的上下文,例如本地目录、Git URL,甚至其他 Bake 目标。Bake 会根据上下文值的模式自动确定上下文的类型。

上下文类型示例
容器镜像docker-image://alpine@sha256:0123456789
Git URLhttps://github.com/user/proj.git
HTTP URLhttps://example.com/files
本地目录../path/to/src
构建目标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 的名称。 这与 --file 标志docker build 命令中相同。

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

授权是构建过程运行所需的权限。

目前支持的授权包括:

  • network.host: 允许构建使用访问主机网络的命令。在 Dockerfile 中,使用 RUN --network=host 以启用主机网络运行命令。

  • security.insecure: 允许构建在不受默认安全沙箱限制的特权容器中运行命令。此类容器可能会访问和修改系统资源。在 Dockerfile 中,使用 RUN --security=insecure 在特权容器中运行命令。

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 的矩阵策略]的工作方式类似。 你可以使用它来减少你的烘焙定义中的重复。

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 会构建所有可能的变体。

以下示例构建四个目标:

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

每个矩阵目标的多个值

如果你想要基于不止一个值来区分矩阵, 可以使用映射作为矩阵值。Bake 会为每个映射创建一个目标, 你可以使用点表示法访问嵌套值。

以下示例构建两个目标:

  • app-foo-1-0
  • app-bar-2-0
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 网络模式需要提升的权限,可能存在安全风险。 你可以通过向 docker buildx bake 命令传递 --allow=network.host 来授予该权限,或者如果你使用的是交互式终端,可以在提示时确认权限。

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

配置构建器在构建目标时是否尝试拉取镜像。 这与 --pulldocker build 标志相同。 以下示例强制构建器始终拉取构建目标中引用的所有镜像。

target "default" {
  pull = true
}

target.secret

定义要向构建目标公开的机密。 这与 --secret 标志相同。

variable "HOME" {
  default = null
}

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

这允许你在Dockerfile中 挂载机密

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指令时为构建容器分配的共享内存大小。

格式为 <number><unit>number 必须大于 0。单位是可选的,可以是 b(字节)、k(千字节)、m(兆字节)或 g(千兆字节)。如果省略单位,系统将使用字节。

这与 docker build--shm-size 标志相同。

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

注意

在大多数情况下,建议让构建器自动确定适当的配置。只有在复杂构建场景需要特定性能调优时,才应考虑手动调整。

target.ssh

定义要暴露给构建的SSH代理套接字或密钥。 这与 --ssh 标志相同。 如果需要在构建期间访问私有仓库,这将非常有用。

target "default" {
  ssh = ["default"]
}
FROM alpine
RUN --mount=type=ssh \
    apk add git openssh-client \
    && install -m 0700 -d ~/.ssh \
    && ssh-keyscan github.com >> ~/.ssh/known_hosts \
    && git clone git@github.com:user/my-private-repo.git

target.tags

用于构建目标的镜像名称和标签。 这与 --tag 标志相同。

target "default" {
  tags = [
    "org/repo:latest",
    "myregistry.azurecr.io/team/image:v1"
  ]
}

target.target

设置目标构建阶段为 build。 这与 --target 标志 相同。

target "default" {
  target = "binaries"
}

target.ulimits

Ulimits 在使用 RUN 指令时会覆盖构建容器的默认 ulimits,并以软限制和硬限制的形式指定,如下所示: <type>=<soft limit>[:<hard limit>],例如:

target "app" {
  ulimits = [
    "nofile=1024:1024"
  ]
}

注意

如果不提供 hard limit,则两个值都会使用 soft limit。如果没有设置 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"]
  }

在将变量插入到属性中之前, 您必须先在烘焙文件中声明它, 如下例所示。

$ 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

功能

A 一组通用函数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 函数 页面以获取更多详细信息。