1. 概述
Docker 是一个流行的部署工具,它使我们能够打包并运行应用程序。由于其广泛采用,经常需要根据不同的需求扩展功能。因此,为了实现这一点,一些部署会使用 Docker 插件。例如,如果我们要在不同主机上持久化数据,我们会使用存储卷插件。另一个常用插件是 Docker buildx。它通过使用 BuildKit 建设器扩展了 图像 的构建能力。因此,借助此插件,我们可以为不同的平台和架构构建图像。此外,它支持带有自定义上下文的并行多阶段构建。
本文档将介绍 Docker buildx 的入门知识。
2. 安装 buildx
首先,对于 buildx 能够运行,我们需要安装 Docker。Docker buildx 支持从 Docker 引擎 19.00 版本开始。
2.1. 检查 Docker 版本
让我们首先检查我们的 Docker 版本:
$ docker --version
Docker version 19.03.8, build afacb8b
在这种情况下,我们支持 buildx。
2.2. 启用实验性功能
接下来,通过设置环境变量来启用 Docker 实验性功能:
$ export DOCKER_CLI_EXPERIMENTAL=enabled
为了确保设置在会话结束后仍然有效,我们将其添加到 $HOME/.bashrc 中以适用于 Bash。
2.3. 验证 buildx
有了这些设置,我们现在应该可以访问 buildx:
$ docker buildx
Usage: docker buildx COMMAND
Build with BuildKit
Management Commands:
imagetools Commands to work on images in registry
Commands:
bake Build from a file
build Start a build
create Create a new builder instance
inspect Inspect current builder instance
ls List builder instances
rm Remove a builder instance
stop Stop builder instance
use Set the current builder instance
version Show buildx version information
Run 'docker buildx COMMAND --help' for more information on a command.
输出显示了常见的子命令及其语法。
2.4. 故障排查
有时,尽管一切准备就绪,但在执行 buildx 的 docker 子命令时仍可能会出现错误:
$ docker buildx build .
docker: 'buildx' is not a docker command.
See 'docker --help'
即使我们似乎拥有 Docker 19 及以上版本,这种情况也可能发生。通常,这种问题的原因是使用了 docker.io 包。
无论如何,更正此问题的主要方法之一是安装 docker-buildx 包。例如,让我们使用 APT:
$ apt install docker-buildx
或者 如果我们使用官方 Docker 仓库 (https://docs.docker.com/engine/install/) ,则安装 docker-buildx-plugin 包:
$ apt install docker-buildx-plugin
通常,后者是更好的方法,因为它得到官方支持。
要找出可用的包(如果有),我们也可以使用本地包管理器:
$ apt list --installed | grep buildx
如果所有其他方法都失败, 我们还可以重启 Docker 主机作为潜在的修复方法。
3. 使用 buildx 构建
buildx 执行所有 Docker build 能力。因此,我们可以像 build 一样执行它们。例如,指定目标平台、构建缓存和输出配置。除此之外,buildx 提供额外的功能。
主要的是,buildx 提供了同时为多个平台构建图像的能力。此外,我们可以在单个 dockerfile 内进行多阶段构建,以构建较小的图像。最后,build**x 具有在构建过程中自定义输入、参数或变量的能力。
让我们通过创建实例来深入研究一个示例:
$ docker buildx create --name ourbuilder
ourbuilder
这创建了一个名为 ourbuilder 的构建实例。
接下来,我们将它设置为活动目录:
$ docker buildx use ourbuilder
之后,让我们创建一个 dockerfile 来运行简单的 node 应用程序:
# Base image
FROM node:14-alpine
# Set working directory
WORKDIR /app
# Copy application files
COPY . .
# Install dependencies
RUN npm install --production
# Expose the port
EXPOSE 3000
# Start the application
CMD ["node", "app.js"]
在这里,我们使用 node.js 基础图像,并将工作目录设置为 /app。然后,我们将 app 文件复制到容器中。最后,我们安装所有依赖项,暴露端口 3000 并启动应用:
$ docker buildx build --platform linux/amd64,linux/arm64 -t ourapp:latest .
time="2023-06-01T07:13:20+03:00" level=warning msg="No output specified for docker-container driver.
Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load"
#1 [internal] booting buildkit
#1 pulling image moby/buildkit:buildx-stable-1
#1 pulling image moby/buildkit:buildx-stable-1 73.2s done
#1 creating container buildx_buildkit_ourbuilder0
#1 creating container buildx_buildkit_ourbuilder0 2.1s done
#1 DONE 75.4s
#3 [internal] load .dockerignore
#3 transferring context: 0.0s
#3 transferring context: 2B 0.1s done
#3 DONE 0.3s
#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 294B 0.0s done
#2 DONE 0.4s
#4 [linux/amd64 internal] load metadata for docker.io/library/node:14-alpin...
#4 DONE 4.7s
.... truncated .....
我们使用 –platform 标志指定目标平台。在这种情况下,我们针对 x86(Linux/amd64)和 ARM(Linux/arm64)架构。此外,我们提供标签 -t ourapp:latest,以便图像包含名称 ourapp 和最新标签。句点表示构建上下文,即当前目录。
Docker buildx 自动处理多平台构建,为每个目标架构生成单独的图像。
注意: 当使用 buildx 多个平台时,除非指定,否则图像不会被加载到 Docker 中。要将图像加载到 Docker 中,请使用 --load
标志:
$ docker buildx build --load -t ourapp:latest .
设置展示了 BuildX 在有效地管理构建方面的灵活性。
4. 总结
在本文档中,我们探讨了 Docker buildx 这个扩展 Docker 图像构建和管理能力的工具。它简化了流程,支持并行构建、自定义构建上下文和多阶段构建。