简介
Docker Buildx 扩展了标准的 Docker build 命令,增加了用于创建多架构镜像的增强功能。然而,用户在使用此工具时,经常会遇到 "docker buildx build requires exactly 1 argument" 错误。本教程将全面指导你理解 Docker Buildx,诊断这个常见错误,并实施有效的解决方案。
通过完成本实验,你将获得设置 Docker Buildx、创建 Docker 镜像、解决 "requires exactly 1 argument" 错误以及为多种架构构建镜像的实践经验。这些技能对于现代容器化应用程序的开发和部署至关重要。
设置 Docker Buildx
Docker Buildx 随 Docker 预安装,但需要在开始使用前进行正确设置。在这一步中,我们将验证 Docker 是否已安装,启用 Docker Buildx,并创建我们的第一个 builder 实例。
验证 Docker 安装
首先,让我们确认 Docker 已安装并在我们的系统上运行:
docker --version
你应该看到类似如下的输出:
Docker version 20.10.21, build baeda1f
这确认了 Docker 已安装并可以使用。
理解 Docker Buildx
Docker Buildx 是一个 CLI 插件,它使用 BuildKit 扩展了 Docker 的功能。它支持:
- 同时为多个平台(如 AMD64、ARM64)构建镜像
- 更有效的层缓存
- 改进的构建性能
- 高级构建功能
创建 Docker Buildx Builder
让我们创建一个新的 Docker Buildx builder 并使用它:
docker buildx create --name mybuilder --use
输出应该类似于:
mybuilder
现在,让我们验证我们的 builder 是否已创建并设置为默认值:
docker buildx ls
你应该看到类似如下的输出:
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
mybuilder * docker-container
mybuilder0 unix:///var/run/docker.sock inactive
default docker
default default running linux/amd64, linux/386
mybuilder 旁边的星号 (*) 表示它是当前活动的 builder。
检查 Builder
让我们检查一下 builder 的详细信息:
docker buildx inspect mybuilder
这将向你显示 builder 的配置,包括支持的平台及其当前状态。
现在我们已经成功设置了 Docker Buildx,我们准备好继续创建 Dockerfile 以与我们的 builder 一起使用。
创建一个简单的 Dockerfile 用于测试
在使用 Docker Buildx 构建镜像之前,我们需要创建一个简单的 Dockerfile。这将作为我们的测试用例,用于理解 "requires exactly 1 argument" 错误。
理解 Dockerfile
Dockerfile 是一个文本文件,其中包含构建 Docker 镜像的指令。它自动化了创建具有特定配置的容器的过程。
让我们为我们的项目创建一个目录:
mkdir -p ~/project/buildx-test
cd ~/project/buildx-test
创建一个基本的 Dockerfile
现在,让我们使用 nano 文本编辑器创建一个简单的 Dockerfile:
nano Dockerfile
将以下内容复制并粘贴到 Dockerfile 中:
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
curl \
nginx \
&& rm -rf /var/lib/apt/lists/*
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
按 Ctrl+O,然后按 Enter 保存,再按 Ctrl+X 退出 nano。
让我们分解一下这个 Dockerfile:
FROM ubuntu:22.04- 使用 Ubuntu 22.04 作为基础镜像RUN apt-get update...- 更新软件包列表并安装 curl 和 nginxEXPOSE 80- 指示容器将监听端口 80CMD ["nginx", "-g", "daemon off;"]- 在容器启动时以前台模式运行 nginx
创建一个 .dockerignore 文件
.dockerignore 文件有助于排除构建上下文中不需要的文件和目录,从而使构建更快、更高效:
nano .dockerignore
添加以下内容:
.git
.gitignore
*.md
按 Ctrl+O,然后按 Enter 保存,再按 Ctrl+X 退出 nano。
验证项目结构
让我们检查一下我们的文件是否已正确创建:
ls -la
你应该看到类似如下的输出:
total 16
drwxrwxr-x 2 labex labex 4096 Jan 1 00:00 .
drwxr-xr-x 3 labex labex 4096 Jan 1 00:00 ..
-rw-rw-r-- 1 labex labex 21 Jan 1 00:00 .dockerignore
-rw-rw-r-- 1 labex labex 159 Jan 1 00:00 Dockerfile
现在我们有了一个基本的 Dockerfile,我们准备好测试 Docker Buildx 并在下一步中探索 "requires exactly 1 argument" 错误。
理解并解决 "Requires Exactly 1 Argument" 错误
在这一步中,我们将故意触发 "requires exactly 1 argument" 错误,以了解其原因,然后学习如何解决它。
触发错误
首先,如果我们还没有进入项目目录,让我们导航到它:
cd ~/project/buildx-test
现在,让我们尝试使用 Docker Buildx 构建镜像,但没有指定构建上下文:
docker buildx build
你应该看到类似如下的错误消息:
"docker buildx build" requires exactly 1 argument.
See 'docker buildx build --help'.
Usage: docker buildx build [OPTIONS] PATH | URL | -
此错误发生的原因是 docker buildx build 命令需要一个构建上下文(包含 Dockerfile 的目录)作为参数。
理解错误
"requires exactly 1 argument" 错误意味着 Docker Buildx 需要知道在哪里找到构建镜像所需的文件。此参数通常是包含你的 Dockerfile 的目录的路径(构建上下文)。
触发此错误的常见情况包括:
- 忘记指定构建上下文
- 使用不正确的命令语法
- 将选项放置在错误的顺序
纠正错误
让我们通过添加构建上下文来修复该命令。最简单的方法是使用 . 来指示当前目录:
docker buildx build .
这次,Docker 将启动构建过程,但我们会注意到它没有标记镜像,这使得以后很难引用它。
如果构建仍在运行,让我们使用 Ctrl+C 停止构建,然后使用正确的标签重试:
docker buildx build -t nginx-test:latest .
你应该看到显示构建进度的输出:
[+] Building 12.8s (7/7) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 203B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 34B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:22.04 0.5s
=> [1/3] FROM docker.io/library/ubuntu:22.04@sha256:... 0.0s
=> CACHED [2/3] RUN apt-get update && apt-get install -y curl nginx 0.0s
=> CACHED [3/3] EXPOSE 80 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:... 0.0s
=> => naming to docker.io/library/nginx-test:latest 0.0s
使用不同的 Buildx 选项
让我们使用 Docker Buildx 探索一些额外的选项:
- 构建并将镜像加载到 Docker 的本地镜像存储中:
docker buildx build --load -t nginx-test:local .
- 在不使用构建缓存的情况下构建(强制全新构建):
docker buildx build --no-cache -t nginx-test:nocache .
- 构建并仅输出最终的镜像 ID:
docker buildx build -q -t nginx-test:quiet .
验证已构建的镜像
让我们检查一下我们构建的镜像:
docker images | grep nginx-test
你应该看到类似如下的输出:
nginx-test quiet abcdef123456 5 minutes ago 123MB
nginx-test nocache fedcba654321 5 minutes ago 123MB
nginx-test local 123456abcdef 5 minutes ago 123MB
nginx-test latest abcdef123456 5 minutes ago 123MB
现在你了解了 Docker Buildx 中常见的 "requires exactly 1 argument" 错误,并且知道如何使用各种选项正确构建镜像。
使用 Docker Buildx 构建多架构镜像
Docker Buildx 最强大的功能之一是它能够同时为多个架构构建镜像。在这一步中,我们将学习如何创建多架构镜像。
理解多架构镜像
多架构镜像允许使用相同的镜像名称在不同的平台(如 AMD64、ARM64 等)上运行。当拉取镜像时,Docker 会自动为宿主架构选择合适的版本。
这尤其适用于:
- 支持基于 x86 和 ARM 的设备
- 确保你的应用程序在各种云提供商上运行
- 为具有不同架构的物联网设备构建
设置多架构构建
Docker Buildx 需要配置为进行多架构构建。首先,让我们确保我们的构建器支持此功能:
docker buildx inspect --bootstrap mybuilder
如果你看到关于构建器不可用的错误,让我们使用正确的配置重新创建它:
docker buildx rm mybuilder
docker buildx create --name mybuilder --driver docker-container --bootstrap --use
创建多架构镜像
现在,让我们为多个架构构建我们的 Nginx 镜像:
docker buildx build --platform linux/amd64,linux/arm64 -t nginx-test:multi .
你可能会看到类似如下的错误消息:
error: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")
发生这种情况是因为默认的 Docker 驱动程序不支持多架构构建。让我们修改我们的方法。
为了演示目的,我们将分别为特定平台构建:
docker buildx build --platform linux/amd64 -t nginx-test:amd64 --load .
这会专门为 AMD64 架构构建镜像,并将其加载到 Docker 的本地镜像存储中。
使用构建参数
Docker Buildx 允许我们使用构建参数来定制我们的构建。让我们修改我们的 Dockerfile 以使用构建参数:
nano Dockerfile
将 Dockerfile 内容更新为:
FROM ubuntu:22.04
ARG PACKAGE=nginx
RUN apt-get update && apt-get install -y \
curl \
${PACKAGE} \
&& rm -rf /var/lib/apt/lists/*
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
按 Ctrl+O,然后按 Enter 保存,再按 Ctrl+X 退出 nano。
现在我们可以使用自定义软件包构建镜像:
docker buildx build --build-arg PACKAGE=nginx-extras -t nginx-extras:latest .
推送到注册表(可选)
要充分利用多架构镜像,你通常会将它们推送到注册表。这需要 Docker Hub 凭据或私有注册表。在真实世界中,该命令将如下所示:
## 仅供参考 - 本实验不需要
## docker buildx build --platform linux/amd64,linux/arm64 -t username/nginx-test:multi --push .
检查镜像
让我们检查一下我们创建的镜像:
docker images | grep nginx
你应该看到类似如下的输出:
nginx-extras latest abcdef123456 1 minute ago 130MB
nginx-test amd64 123456abcdef 2 minutes ago 123MB
nginx-test latest fedcba654321 10 minutes ago 123MB
测试我们的镜像
最后,让我们使用我们的镜像运行一个容器来验证它是否有效:
docker run -d --name test-nginx -p 8080:80 nginx-test:latest
检查容器是否正在运行:
docker ps
你应该看到输出,表明你的容器正在运行:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
abcdef123456 nginx-test:latest "nginx -g 'daemon of…" 10 seconds ago Up 10 seconds 0.0.0.0:8080->80/tcp test-nginx
让我们使用 curl 命令访问 nginx 服务器,以确保它正在响应:
curl http://localhost:8080
你应该看到默认的 Nginx 欢迎页面 HTML。
完成后,清理容器:
docker stop test-nginx
docker rm test-nginx
恭喜你!你已经成功地使用了 Docker Buildx,理解并解决了 "requires exactly 1 argument" 错误,并且学习了如何为不同的架构创建专门的构建。
总结
在这个实验中,你获得了 Docker Buildx 的实践经验,并学习了如何解决常见的 "requires exactly 1 argument" 错误。以下是你完成的任务:
- 设置 Docker Buildx 并创建了一个构建器实例
- 创建了一个用于测试的基本 Dockerfile
- 遇到了、理解了并解决了 "requires exactly 1 argument" 错误
- 使用各种选项和配置构建了 Docker 镜像
- 学习了多架构镜像构建的基础知识
这些技能为在现代开发环境中与 Docker 合作奠定了坚实的基础,在这些环境中,应用程序通常需要在不同的硬件平台上运行。你现在可以自信地使用 Docker Buildx 来创建高效的、特定于平台的容器镜像,同时避免常见错误。
在你继续 Docker 之旅时,可以考虑探索更高级的 Buildx 功能,将其集成到 CI/CD 管道中,并使用它来构建真正可移植的应用程序,这些应用程序可以在任何地方运行。



