Docker Buildx 怎样构建多架构镜像
来源:17golang原创
时间:2026-10-15 01:56:45 271浏览 收藏
当一台开发机是 Apple Silicon,而线上节点还有 amd64 时,镜像“能构建”并不等于“两个架构都能拉取”。这篇文章用 Docker Buildx 固定一个镜像标签,同时构建 linux/amd64 和 linux/arm64,再把结果推送到仓库,让不同节点按自身架构获取对应镜像。
官方地址:https://docs.docker.com/build/building/multi-platform/
你需要一个可推送的镜像仓库,并完成 Docker 登录。本文示例中的仓库名使用占位符,不代表真实账号或仓库。
先确定最终要看到什么
成功结果有三个特征:构建命令明确写出两个平台;构建结果使用 --push 写入远程仓库;同一个标签下能看到一个镜像索引以及 linux/amd64、linux/arm64 两个平台条目。
不要把本地 docker images 中只出现一个架构的镜像,当成多架构发布已经完成。默认 Docker Engine 的本地镜像存储并不适合直接加载多平台结果,远程仓库才是本文的验收位置。
第一步:准备 Builder 和镜像标签
打开 Docker Desktop 的 Builds 或 Builder 管理入口,先确认当前 Builder 状态为可用。命令行也可以直接查看:
# 查看当前 Buildx builder、节点状态和可用平台 docker buildx ls # 创建一个隔离的容器驱动 builder,并切换到它 docker buildx create --name multiarch-builder --driver docker-container --use # 启动 builder,提前暴露平台支持与初始化错误 docker buildx inspect --bootstrap
把镜像标签先固定下来,例如 registry.example/team/demo:1.0.0。真实使用时替换成你有推送权限的仓库地址;不要把密码、Token 或个人路径写进命令。

第二步:检查 Dockerfile 是否锁死了宿主架构
如果 Dockerfile 只是安装脚本或解释型程序,通常可以直接让基础镜像跟随目标平台。若包含编译步骤,可以利用 BuildKit 自动提供的 BUILDPLATFORM 和 TARGETPLATFORM,把构建工具运行在构建机平台,把产物编译到目标平台。
# 让编译器阶段运行在 builder 原生平台,减少不必要的模拟 FROM --platform=$BUILDPLATFORM golang:1.23-alpine AS build # 这两个参数由 BuildKit 注入,用于区分构建平台和目标平台 ARG BUILDPLATFORM ARG TARGETPLATFORM WORKDIR /src COPY . . # 示例只展示平台参数传递;真实项目应在这里执行可复现的构建命令 RUN echo "build=$BUILDPLATFORM target=$TARGETPLATFORM" > /platform.txt # 最终阶段不要硬编码 linux/amd64,让 --platform 决定基础镜像 FROM alpine:3.20 COPY --from=build /platform.txt /platform.txt
重点是不要在所有 FROM 后面随手写死 linux/amd64。这种写法会让 arm64 构建仍然拿到 amd64 基础层,最终表现为拉取或运行阶段的架构不匹配。
第三步:在构建界面中选择两个平台
在 Docker Desktop 的构建配置中,将 Platforms 设为 linux/amd64 和 linux/arm64,Image tag 填入刚才固定的版本标签。若使用命令行,对应参数是一个逗号分隔列表:
# 明确声明两个 Linux 目标平台,并给结果打固定版本标签 docker buildx build \ --platform linux/amd64,linux/arm64 \ --tag registry.example/team/demo:1.0.0 \ .
这里的 --platform 不只是筛选下载地址,它决定了没有单独指定平台的 FROM 指令将使用哪个目标平台,也决定最终输出需要包含哪些架构。
第四步:用 Push 保存多平台结果
多架构结果不能只依赖本地加载。将输出动作改为推送,并确保前面已经登录仓库:
# 登录目标仓库;凭据由 Docker 凭据存储处理,不写进脚本参数 docker login registry.example # 构建两个平台并直接推送 manifest list 与各平台镜像 docker buildx build \ --platform linux/amd64,linux/arm64 \ --tag registry.example/team/demo:1.0.0 \ --push \ .
在结果验收型流程里,看到构建日志结束只是中间状态。真正的完成点是仓库收到同一标签下的镜像索引与两个平台的镜像清单。--push 相当于选择 registry 输出;不要同时把它理解成“把两个架构都加载到本地 Docker Engine”。
第五步:核对标签和平台条目
打开仓库的镜像标签详情,或使用 Buildx 的元数据工具查看同一个标签。为了避免把真实仓库信息写进文章,下面的结果字段只作为核对形状:
# 读取远程标签的 manifest 信息,确认同一标签包含多个平台 docker buildx imagetools inspect registry.example/team/demo:1.0.0 # 预期重点观察这两个平台,而不是只看本机架构 # linux/amd64 # linux/arm64
界面上应能看到一个 Image index 或 manifest list,以及两个平台子项。digest 每次构建都可能不同,验收重点是标签、平台和推送状态三者是否同时存在。

遇到失败时按这四个位置修正
- Builder 不支持目标平台:先运行
docker buildx inspect --bootstrap,确认节点列出了目标平台;不要只看 Docker 客户端版本。 - 构建很慢:QEMU 模拟容易上手,但编译、压缩等 CPU 密集任务可能明显变慢。可以改用多个原生节点,或在多阶段构建中做交叉编译。
- 推送被拒绝:检查
docker login的仓库域名、镜像命名空间和权限。认证失败和 Dockerfile 平台问题是两类故障,不要混在一起排查。 - 误用
--load:单平台结果适合加载到本地;多平台发布应优先使用--push。如果必须在本机测试,分别指定一个平台构建后再加载。
最后留下可复用的发布清单
- Builder 已启动,并能识别目标平台。
- Dockerfile 没有把最终基础镜像硬编码成宿主架构。
--platform同时包含linux/amd64与linux/arm64。- 标签带有明确版本,不用浮动的临时标签验收。
- 命令使用
--push,仓库结果显示 manifest list 和两个平台条目。
如果你的目标只是让本机启动一个镜像,单平台 --load 会更直接;如果目标是让不同架构节点共享一个版本标签,就按本文的 Buildx、--platform、--push 和仓库平台结果四处一起确认。
常见问题
为什么构建成功但 arm64 节点拉不到镜像?
常见原因是只构建了宿主架构,或使用了 --load 而没有推送多平台索引。先检查构建命令是否列出 arm64,再看远程标签是否真的包含该平台。
一定要手动安装 QEMU 吗?
不一定。Docker 官方的 BuildKit 环境通常会提供常见模拟能力;是否需要额外配置取决于 builder 环境和目标平台。对编译密集项目,原生节点或交叉编译通常更适合。
同一个标签能不能只推送其中一个平台?
可以单独构建一个平台,但这样标签的最终平台集合取决于推送策略和仓库现有清单。需要稳定的多架构交付时,应在一次明确的 Buildx 发布中列出完整平台集合。
-
160 收藏
-
105 收藏
-
420 收藏
-
276 收藏
-
175 收藏
-
259 收藏
-
482 收藏
-
205 收藏
-
249 收藏
-
文章 · 软件教程 | 1小时前 | gitHub actions · 软件教程 · 持续集成 GitHub Actions Required reviewers GitHub Environments 生产部署162 收藏
-
文章 · 软件教程 | 1小时前 | gitHub actions · 软件教程 · 持续集成 · 持续集成 Matrix GitHub Actions strategy.matrix max-parallel310 收藏
-
258 收藏
-
478 收藏
-
文章 · 软件教程 | 1小时前 | 开发环境 · vs code · 软件教程 · shell VS Code 集成终端 Terminal Profiles Select Default Profile388 收藏
-
393 收藏
-
219 收藏
-
208 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习