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.hcl
  7. docker-bake.override.json
  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 表示中,属性是对象,而属性是分配给这些对象的值。

以下示例显示了相同 Bake 文件的 HCL 格式

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列表外部缓存目标
call字符串指定要为目标调用的前端方法。
context字符串位于指定路径或 URL 中的文件集
contexts映射额外的构建上下文
description字符串目标的描述
dockerfile-inline字符串内联 Dockerfile 字符串
dockerfile字符串Dockerfile 位置
entitlements列表构建过程运行所需的权限
extra-hosts列表自定义主机到 IP 映射
inherits列表从其他目标继承属性
labels映射图像元数据
matrix映射定义一组变量,将一个目标分叉为多个目标。
name字符串使用矩阵时覆盖目标名称。
no-cache-filter列表禁用特定阶段的构建缓存
no-cache布尔值完全禁用构建缓存
output列表输出目标
platforms列表目标平台
pull布尔值始终拉取镜像
secret列表要暴露给构建的秘密
shm-size列表/dev/shm 的大小
ssh列表要暴露给构建的 SSH 代理套接字或密钥
tags列表镜像名称和标签
target字符串目标构建阶段
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"
    }
  ]
  annotations = ["index,manifest:org.opencontainers.image.authors=dvdksn"]
}

请阅读 指定注释级别 中支持的级别。

target.attest

attest 属性允许您将 构建证明 应用于目标。此属性接受证明参数的长格式 CSV 版本。

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

target.cache-from

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

target "app" {
  cache-from = [
    {
      type = "s3"
      region = "eu-west-1"
      bucket = "mybucket"
    },
    {
      type = "registry"
      ref = "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"
}

支持的值有

  • build 构建目标(默认)
  • check:评估目标的 构建检查
  • outline:显示目标的构建参数及其默认值(如果可用)
  • targets:列出加载定义中的所有 Bake 目标及其 描述

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

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
Bake 目标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.description

为目标定义一个人类可读的描述,阐明其目的或功能。

target "lint" {
  description = "Runs golangci-lint to detect style errors"
  args = {
    GOLANGCI_LINT_VERSION = null
  }
  dockerfile = "lint.Dockerfile"
}

当与 docker buildx bake --list=targets 选项结合使用时,此属性非常有用,可以在列出 Bake 文件中可用的构建目标时提供更多信息输出。

target.dockerfile-inline

使用字符串值作为构建目标的内联 Dockerfile。

target "default" {
  dockerfile-inline = "FROM alpine\nENTRYPOINT [\"echo\", \"hello\"]"
}

dockerfile-inline 优先于 dockerfile 属性。如果您同时指定两者,Bake 将使用内联版本。

target.dockerfile

用于构建的 Dockerfile 名称。这与 docker build 命令的 --file 标志 相同。

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.extra-hosts

使用 extra-hosts 属性为目标定义自定义主机到 IP 映射。这与向构建命令传递 --add-host 标志具有相同的效果。

target "default" {
  extra-hosts = {
    my_hostname = "8.8.8.8"
  }
}

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 的矩阵策略] 的工作方式类似。您可以使用此功能减少 Bake 定义中的重复。

matrix 属性是从参数名称到值列表的映射。Bake 将值的每个可能组合构建为一个单独的目标。

每个生成的 target 必须 具有唯一的名称。要指定 target 名称应如何解析,请使用 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=。这样,您可以为单个构建步骤设置网络模式,并且所有构建 Dockerfile 的人都将获得一致的行为,而无需向构建命令传递额外的标志。

如果您在 Bake 文件中将网络模式设置为 host,则在调用 bake 命令时还必须授予 network.host 权限。这是因为 host 网络模式需要提升的权限,并且可能存在安全风险。您可以将 --allow=network.host 传递给 docker buildx bake 命令以授予权限,或者如果您使用交互式终端,则可以在提示时确认权限。

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

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

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 必须大于 0。单位是可选的,可以是 b (字节)、k (千字节)、m (兆字节) 或 g (千兆字节)。如果省略单位,系统将使用字节。

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

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

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

target.ssh

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

target "default" {
  ssh = [{ id = "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

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

target "default" {
  target = "binaries"
}

target.ulimits

Ulimits 会覆盖使用 RUN 指令时构建容器的默认 ulimits,并以软限制和硬限制指定,例如:=[:],例如

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" {
  type = string
  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

变量也可以被赋予显式类型。如果提供了类型,它将用于验证默认值(如果已设置)以及任何覆盖。这在使用旨在被覆盖的复杂类型时特别有用。前面的示例可以扩展以应用任意系列的标签。

variable "TAGS" {
  default = ["latest"]
  type = list(string)
}

target "webapp-dev" {
  dockerfile = "Dockerfile.webapp"
  tags = [for tag in TAGS: "docker.io/username/webapp:${tag}"]
}

此示例展示了如何在不更改文件或使用自定义函数/解析的情况下生成三个标签

$ TAGS=dev,latest,2 docker buildx bake webapp-dev

变量类型

以下原始类型可用

  • 字符串
  • 数字
  • 布尔

类型以关键字形式表达;它必须以字面量形式表达

variable "OK" {
  type = string
}

# cannot be an actual string
variable "BAD" {
  type = "string"
}

# cannot be the result of an expression
variable "ALSO_BAD" {
  type = lower("string")
}

指定原始类型对于表明意图(尤其是在未提供默认值时)可能很有价值,但通常情况下,即使没有显式类型,Bake 的行为也会如预期。

复杂类型使用“类型构造函数”表达;它们是

  • tuple([,...])
  • list()
  • set()
  • map()
  • object({=},...})

以下是这些示例,以及如何表达(可选)默认值

# structured way to express "1.2.3-alpha"
variable "MY_VERSION" {
  type = tuple([number, number, number, string])
  default = [1, 2, 3, "alpha"]
}

# JDK versions used in a matrix build
variable "JDK_VERSIONS" {
  type = list(number)
  default = [11, 17, 21]
}

# better way to express the previous example; this will also
# enforce set semantics and allow use of set-based functions
variable "JDK_VERSIONS" {
  type = set(number)
  default = [11, 17, 21]
}

# with the help of lookup(), translate a 'feature' to a tag
variable "FEATURE_TO_NAME" {
  type = map(string)
  default = {featureA = "slim", featureB = "tiny"}
}

# map a branch name to a registry location
variable "PUSH_DESTINATION" {
  type = object({branch = string, registry = string})
  default = {branch = "main", registry = "prod-registry.invalid.com"}
}

# make the previous example more useful with composition
variable "PUSH_DESTINATIONS" {
  type = list(object({branch = string, registry = string}))
  default = [
    {branch = "develop", registry = "test-registry.invalid.com"},
    {branch = "main", registry = "prod-registry.invalid.com"},
  ]
}

请注意,在每个示例中,即使不存在类型,默认值也是有效的。如果省略类型,前三个都将被视为 tuple;您将受限于对 tuple 操作的函数,例如,无法添加元素。类似地,第三个和第四个都将被视为 object,具有该类型的限制和语义。简而言之,在没有类型的情况下,任何用 [] 分隔的值都是 tuple,任何用 {} 分隔的值都是 object。复杂类型的显式类型不仅提供了使用适用于该专门类型的功能的能力,而且还是提供覆盖的先决条件。

注意

有关更多详细信息,请参阅 HCL 类型表达式 页面。

覆盖变量

正如 变量介绍 中所述,原始类型(stringnumberbool)可以在没有类型的情况下被覆盖,并且通常会按预期工作。(当未提供显式类型时,如果默认值缺少 {}[] 分隔符,则变量被假定为原始类型;既没有类型也没有默认值的变量被视为 string。)当然,这些相同的覆盖也可以与显式类型一起使用;它们可能有助于处理您希望 VAR=truestring 的边缘情况,而在没有类型的情况下,它可能是 stringbool,具体取决于其使用方式/位置。复杂类型的变量只能在提供类型时被覆盖。这仍然通过环境变量完成,但值可以通过 CSV 或 JSON 提供。

CSV 覆盖

这被认为是规范方法,非常适合交互式使用。假设 listset 将是最常见的复杂类型,也是最常见的旨在被覆盖的复杂类型。因此,listset(以及 tuple;尽管被视为结构类型,但在这方面它更像集合类型)具有完整的 CSV 支持。

mapobject 的支持有限,不支持复合类型;对于这些高级情况,可以使用 使用 JSON 的替代机制。

JSON 覆盖

覆盖也可以通过 JSON 提供。这是提供某些复杂类型的唯一可用方法,如果覆盖已经是 JSON(例如,如果它们来自 JSON API),则可能很方便。当处理难以或不可能使用 CSV 指定的值(例如,包含引号或逗号的值)时,也可以使用它。要使用 JSON,只需在变量名称后附加 _JSON。在此人为设计的示例中,CSV 无法处理第二个值;尽管是支持的 CSV 类型,但必须使用 JSON

variable "VALS" {
  type = list(string)
  default = ["some", "list"]
}
$ cat data.json
["hello","with,comma","with\"quote"]
$ VALS_JSON=$(< data.json) docker buildx bake

# CSV equivalent, though the second value cannot be expressed at all 
$ VALS='hello,"with""quote"' docker buildx bake

此示例说明了一些优先规则和使用规则

variable "FOO" {
  type = string
  default = "foo"
}

variable "FOO_JSON" {
  type = string
  default = "foo"
}

变量 FOO 只能使用 CSV 覆盖,因为通常用于 JSON 覆盖的 FOO_JSON 已经是一个定义的变量。由于 FOO_JSON 是一个实际变量,因此设置该环境变量将预期为 CSV 值。对于此变量,JSON 覆盖是可能的,使用环境变量 FOO_JSON_JSON

# These three are all equivalent, setting variable FOO=bar
$ FOO=bar docker buildx bake <...>
$ FOO='bar' docker buildx bake <...>
$ FOO="bar" docker buildx bake <...>

# Sets *only* variable FOO_JSON; FOO is untouched
$ FOO_JSON=bar docker buildx bake <...>

# This also sets FOO_JSON, but will fail due to not being valid JSON
$ FOO_JSON_JSON=bar docker buildx bake <...>

# These are all equivalent
$ cat data.json
"bar"
$ FOO_JSON_JSON=$(< data.json) docker buildx bake <...>
$ FOO_JSON_JSON='"bar"' docker buildx bake <...>
$ FOO_JSON=bar docker buildx bake <...>

# This results in setting two different variables, both specified as CSV (FOO=bar and FOO_JSON="baz")
$ FOO=bar FOO_JSON='"baz"' docker buildx bake <...>

# These refer to the same variable with FOO_JSON_JSON having precedence and read as JSON (FOO_JSON=baz)
$ FOO_JSON=bar FOO_JSON_JSON='"baz"' docker buildx bake <...>

内置变量

以下变量是内置变量,您可以在 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"]
  }

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

$ 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

函数

HCL 文件中可使用 go-cty 提供的一组 通用函数

# 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 函数 页面。

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.