如何使用 docker buildx bake 命令构建多个目标

DockerDockerBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,你将学习如何高效使用 docker buildx bake 命令来通过单一配置文件管理和构建多个 Docker 镜像目标。我们将从创建一个 docker-bake.hcl 文件开始,该文件定义了具有不同配置的多个构建目标。

通过动手实践,你将练习构建 bake 文件中定义的特定目标、列出可用目标、使用命令行标志覆盖目标配置,以及在不实际执行构建的情况下预览构建配置。本实验将帮助你掌握为复杂项目优化 Docker 镜像构建流程的技能。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker/ImageOperationsGroup -.-> docker/images("List Images") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/images -.-> lab-555044{{"如何使用 docker buildx bake 命令构建多个目标"}} docker/build -.-> lab-555044{{"如何使用 docker buildx bake 命令构建多个目标"}} end

创建包含多个目标的简单 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-devmy-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_ENVRUN 指令在构建过程中打印构建环境,CMD 指令设置了从此镜像启动容器时运行的默认命令。

保存 Dockerfile 并退出 nano

你现在已成功创建了一个包含两个目标的 docker-bake.hcl 文件以及与之配套的简单 Dockerfile

使用 docker buildx bake 构建特定目标

在上一步中,我们创建了一个包含两个构建目标 my-app-devmy-app-proddocker-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

你应该能在镜像列表中看到标签为 devmy-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:devmy-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-devmy-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

现在你应该能在镜像列表中看到标签为 stagingmy-app 镜像,以及之前步骤中创建的 devprod 标签。

你还可以覆盖其他属性,例如构建参数。让我们构建 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 在简化复杂多镜像构建工作流程方面的灵活性和强大功能。