介绍
在本实验中,你将学习如何高效使用 docker buildx bake 命令来通过单一配置文件管理和构建多个 Docker 镜像目标。我们将从创建一个 docker-bake.hcl 文件开始,该文件定义了具有不同配置的多个构建目标。
通过动手实践,你将练习构建 bake 文件中定义的特定目标、列出可用目标、使用命令行标志覆盖目标配置,以及在不实际执行构建的情况下预览构建配置。本实验将帮助你掌握为复杂项目优化 Docker 镜像构建流程的技能。
创建包含多个目标的简单 docker-bake.hcl 文件
在本步骤中,我们将创建一个基础的 docker-bake.hcl 文件。该文件使用 HCL (HashiCorp Configuration Language) 格式,允许你为 Docker 镜像定义多个构建目标。当你需要不同的构建配置或希望从单一代码源构建多个相关镜像时,这特别有用。
首先,导航至 ~/project 目录,这是本实验的工作目录。
cd ~/project
现在,让我们使用 nano 编辑器创建一个名为 docker-bake.hcl 的新文件。
nano docker-bake.hcl
在 nano 编辑器中粘贴以下内容。该文件定义了两个构建目标:my-app-dev 和 my-app-prod。每个目标都指定了要使用的 Dockerfile (Dockerfile)、构建上下文 (.) 以及生成镜像的标签。
target "my-app-dev" {
dockerfile = "Dockerfile"
context = "."
tags = ["my-app:dev"]
}
target "my-app-prod" {
dockerfile = "Dockerfile"
context = "."
tags = ["my-app:prod"]
args = {
BUILD_ENV = "production"
}
}
在此文件中:
target "my-app-dev"定义了一个名为my-app-dev的目标dockerfile = "Dockerfile"指定构建应使用上下文中的Dockerfile文件context = "."将构建上下文设置为当前目录tags = ["my-app:dev"]为生成的镜像分配my-app:dev标签target "my-app-prod"定义了另一个名为my-app-prod的目标- 同样使用
Dockerfile和当前目录作为上下文 tags = ["my-app:prod"]为此镜像分配my-app:prod标签args = { BUILD_ENV = "production" }在构建此目标时向 Dockerfile 传递值为production的构建参数BUILD_ENV
按 Ctrl + S 保存文件,按 Ctrl + X 退出 nano。
接下来,我们需要一个简单的 Dockerfile 供 bake 文件引用。在同一目录下创建名为 Dockerfile 的文件。
nano Dockerfile
将以下内容粘贴到 Dockerfile 中:
FROM alpine:latest
ARG BUILD_ENV=development
RUN echo "Building for environment: $BUILD_ENV"
CMD ["echo", "Hello from $BUILD_ENV environment!"]
此 Dockerfile 使用 alpine:latest 基础镜像。它定义了一个默认值为 development 的构建参数 BUILD_ENV。RUN 指令在构建过程中打印构建环境,CMD 指令设置了从此镜像启动容器时运行的默认命令。
保存 Dockerfile 并退出 nano。
你现在已成功创建了一个包含两个目标的 docker-bake.hcl 文件以及与之配套的简单 Dockerfile。
使用 docker buildx bake 构建特定目标
在上一步中,我们创建了一个包含两个构建目标 my-app-dev 和 my-app-prod 的 docker-bake.hcl 文件。现在,我们将使用 docker buildx bake 命令来构建该文件中定义的特定目标。
docker buildx bake 命令允许你基于 bake 文件中定义的配置构建镜像。通过在命令后指定目标名称,你可以指示 Buildx 仅构建该特定目标。
让我们构建 my-app-dev 目标。请确保你位于 ~/project 目录中。
cd ~/project
现在执行以下命令:
docker buildx bake my-app-dev
该命令将读取当前目录中的 docker-bake.hcl 文件并构建名为 my-app-dev 的目标。你将看到显示构建过程的输出,包括 Dockerfile 中定义的步骤。
[+] Building 0.0s (0/0)
... (build output) ...
构建完成后,你可以通过列出本地 Docker 镜像来验证 my-app:dev 镜像是否已创建。
docker images
你应该能在镜像列表中看到标签为 dev 的 my-app 镜像。
现在,让我们构建 my-app-prod 目标。该目标包含一个设置为 production 的构建参数 BUILD_ENV。
docker buildx bake my-app-prod
观察输出。在构建过程中,你应该能看到 Building for environment: production 这一行,这确认了构建参数已正确传递。
[+] Building 0.0s (0/0)
... (build output showing "Building for environment: production") ...
此构建完成后,再次列出你的镜像。
docker images
你现在应该能在镜像列表中同时看到 my-app:dev 和 my-app:prod。
通过使用 docker buildx bake 后跟目标名称,你可以选择性地构建 bake 文件中定义的不同配置。
列出 bake 文件中可用的构建目标
在前面的步骤中,我们创建了一个 docker-bake.hcl 文件并从中构建了特定目标。有时,你可能希望查看 bake 文件中定义的所有可用目标而无需实际构建它们。docker buildx bake 命令提供了实现这一需求的方法。
要列出可用目标,你可以直接运行不带任何目标名称的 docker buildx bake 命令。默认情况下,该命令会读取当前目录中的 docker-bake.hcl 文件并显示所有已定义目标的名称。
请确保你位于存放 docker-bake.hcl 文件的 ~/project 目录中。
cd ~/project
现在执行以下命令:
docker buildx bake
你将看到类似以下的输出,其中列出了 docker-bake.hcl 文件中定义的目标:
my-app-dev
my-app-prod
此输出显示了我们之前在 docker-bake.hcl 文件中定义的两个目标:my-app-dev 和 my-app-prod。这是快速了解 bake 文件中可用构建配置的便捷方式。
该命令对于理解 bake 文件的结构以及识别可构建目标非常有用。
使用 --set 参数覆盖目标配置
在本步骤中,我们将学习如何通过 docker buildx bake 命令的 --set 标志来覆盖 docker-bake.hcl 文件中定义的目标配置。当需要在不修改 bake 文件本身的情况下对目标配置进行微调时,这个功能非常实用。
--set 标志允许你覆盖目标的特定属性,其语法格式为 target_name.attribute=value。
假设我们需要构建 my-app-dev 目标,但希望使用不同的标签(例如 my-app:staging),就可以通过 --set 标志实现。
请确保你位于 ~/project 目录中。
cd ~/project
现在执行以下命令:
docker buildx bake my-app-dev --set my-app-dev.tags=my-app:staging
该命令中:
my-app-dev是我们正在构建的目标名称--set my-app-dev.tags=my-app:staging覆盖了my-app-dev目标的tags属性,将其值设为my-app:staging
你将看到构建过程输出。
[+] Building 0.0s (0/0)
... (build output) ...
构建完成后,列出本地 Docker 镜像以验证新标签的镜像是否已创建。
docker images
现在你应该能在镜像列表中看到标签为 staging 的 my-app 镜像,以及之前步骤中创建的 dev 和 prod 标签。
你还可以覆盖其他属性,例如构建参数。让我们构建 my-app-prod 目标,但将 BUILD_ENV 参数覆盖为 qa。
docker buildx bake my-app-prod --set my-app-prod.args.BUILD_ENV=qa
观察构建输出。你应该能看到 Building for environment: qa,这表明构建参数已成功覆盖。
[+] Building 0.0s (0/0)
... (build output showing "Building for environment: qa") ...
--set 标志提供了一种灵活的方式,让你可以直接通过命令行自定义构建配置,而无需修改 bake 文件。
打印最终配置而不执行构建
在这最后一步中,我们将探索如何查看 docker buildx bake 将用于特定目标的最终配置(包括通过 --set 标志应用的任何覆盖),而无需实际触发构建。这在调试 bake 文件以及构建前理解有效配置时非常有用。
docker buildx bake 的 --print 标志允许你以 JSON 格式输出解析后的配置。
请确保你位于 ~/project 目录中。
cd ~/project
让我们打印 my-app-dev 目标的配置。
docker buildx bake my-app-dev --print
该命令将输出从 docker-bake.hcl 文件派生的 my-app-dev 目标配置的 JSON 表示。
{
"target": {
"my-app-dev": {
"dockerfile": "Dockerfile",
"context": ".",
"tags": ["my-app:dev"]
}
}
}
现在,让我们看看 --set 标志如何影响打印的配置。我们将打印 my-app-dev 的配置,同时将标签覆盖为 my-app:testing。
docker buildx bake my-app-dev --set my-app-dev.tags=my-app:testing --print
观察输出结果。JSON 输出中的 tags 属性现在应该反映被覆盖的值。
{
"target": {
"my-app-dev": {
"dockerfile": "Dockerfile",
"context": ".",
"tags": ["my-app:testing"]
}
}
}
同样地,你可以打印 my-app-prod 目标的配置并覆盖其构建参数。
docker buildx bake my-app-prod --set my-app-prod.args.BUILD_ENV=staging --print
my-app-prod 目标的 JSON 输出将显示带有被覆盖 BUILD_ENV 值的 args。
{
"target": {
"my-app-prod": {
"dockerfile": "Dockerfile",
"context": ".",
"tags": ["my-app:prod"],
"args": {
"BUILD_ENV": "staging"
}
}
}
}
--print 标志是一个有价值的工具,可用于验证你的 bake 文件配置,并在启动可能耗时的构建之前理解覆盖是如何应用的。
总结
在本实验中,我们学习了如何利用 docker buildx bake 命令来管理和构建在单个 docker-bake.hcl 文件中定义的多个 Docker 镜像目标。我们首先创建了一个基础的 docker-bake.hcl 文件,其中包含多个独立的目标,每个目标都指定了其 Dockerfile、上下文、标签和构建参数。
随后,我们探索了如何使用 docker buildx bake <target_name> 从 bake 文件中构建特定目标,列出文件中所有可用目标,通过 --set 标志动态覆盖目标配置,以及使用 --print 标志在不实际执行构建的情况下预览最终的构建配置。这些步骤展示了 docker buildx bake 在简化复杂多镜像构建工作流程方面的灵活性和强大功能。



