Docker buildx 多架构镜像实战:一次构建 amd64+arm64,告别 exec format error
Docker buildx 多架构镜像实战:一次构建 amd64arm64,告别 exec format error你在 M 系列 Mac(arm64)上docker build打了个镜像,推到仓库,部署到云上的 x86 服务器(amd64),容器起不来,日志一行:exec /app: exec format error或者反过来:在 x86 CI 上构建的镜像,拉到树莓派、arm 云主机上跑不了。根因是镜像里的二进制是按构建机的 CPU 架构编译的,架构不匹配,内核根本没法执行。解法不是给每个架构各建一个仓库,而是用docker buildx一次构建出多架构镜像,推成一个 manifest list。用户docker pull同一个 tag,Docker 会自动挑对应自己 CPU 架构的那份。这篇手把手把它跑通。先理解:为什么普通 build 是单架构的docker build默认只为当前机器的架构构建。你可以查镜像的架构:dockerinspect--format{{.Architecture}}myapp:latest# arm64 ← 在 M1 Mac 上就是这个推上去后,x86 服务器拉下来,架构对不上,exec format error。你或许试过在服务器上加--platform:dockerrun--platformlinux/amd64 myapp:latest# 靠 QEMU 模拟,能跑但巨慢模拟能应急,但性能差、也不该用在生产。真正的解法是构建期就把两个架构都产出来。一次性准备:开启 buildx 和 QEMUbuildx是 Docker 官方的增强构建器,基于 BuildKit,新版 Docker Desktop / Docker Engine 已自带。要在一台机器上构建非本机架构的镜像,得靠 QEMU 做跨架构模拟编译。先注册 QEMU:# 注册 binfmt handlers,让本机能模拟执行其它架构的二进制dockerrun--privileged--rmtonistiigi/binfmt--installall然后创建一个支持多架构的 builder 实例(默认的 builder 不支持多平台输出):# 创建并切换到一个新的 builderdockerbuildx create--namemultiarch--driverdocker-container--use# 启动并查看它支持哪些平台dockerbuildx inspect--bootstrapinspect输出里Platforms:那行应该能看到linux/amd64, linux/arm64, linux/arm/v7 ...。看到 amd64 和 arm64 就够了。这里有个关键点:--driver docker-container。默认的dockerdriver不支持多平台构建,必须用docker-container驱动(它跑一个独立的 BuildKit 容器)。很多人第一次卡在构建报错说不支持多 platform,就是因为没换 driver。核心命令:一条命令建两个架构并推送dockerbuildx build\--platformlinux/amd64,linux/arm64\-tregistry.example.com/myapp:1.0.0\--push\.三个关键参数:--platform linux/amd64,linux/arm64:一次构建这两个架构。--push:构建完直接推到仓库。多架构构建必须直接 push,不能只--load到本地——因为本地 Docker 镜像存储没法存一个 tag 对应多架构的 manifest list,只有仓库能存。这是第二个高频坑:多平台构建加--load会报错,必须--push(或--output到 tar)。结尾的.:构建上下文。推完后验证一下 manifest,确认两个架构都在:dockerbuildx imagetools inspect registry.example.com/myapp:1.0.0输出会列出一个 manifest list,底下挂着platform: linux/amd64和platform: linux/arm64两个子 manifest。之后不管是 x86 服务器还是 arm 机器,docker pull registry.example.com/myapp:1.0.0都会自动拉对的那份,exec format error彻底消失。Dockerfile 要注意的:别把架构写死多架构构建对 Dockerfile 有要求——凡是下载某架构专属二进制的地方,都不能写死架构。BuildKit 会自动注入几个构建参数,用它们:# syntaxdocker/dockerfile:1 FROM --platform$BUILDPLATFORM golang:1.22 AS builder # BuildKit 自动提供这些 ARG,声明后即可使用 ARG TARGETOS ARG TARGETARCH WORKDIR /src COPY . . # 关键:用 TARGETOS/TARGETARCH 交叉编译出目标架构的二进制 # 这样构建在 amd64 机器上、也能产出 arm64 的可执行文件,不走 QEMU 更快 RUN CGO_ENABLED0 GOOS$TARGETOS GOARCH$TARGETARCH go build -o /app . FROM alpine:3.20 COPY --frombuilder /app /app ENTRYPOINT [/app]几个要点:$BUILDPLATFORM是构建机的架构,$TARGETPLATFORM/$TARGETOS/$TARGETARCH是目标架构。FROM --platform$BUILDPLATFORM让 builder 阶段始终跑在本机架构上(快),再靠 Go 的交叉编译产出目标架构二进制。这比让 QEMU 模拟整个编译过程快得多。ARG TARGETOS/ARG TARGETARCH必须显式声明才能在RUN里用,否则是空值。如果你下载的是预编译工具(比如 kubectl、某个 CLI),记得用$TARGETARCH拼下载 URL,别写死amd64:ARG TARGETARCH RUN curl -fsSL https://example.com/tool-linux-${TARGETARCH} -o /usr/local/bin/tool \ chmod x /usr/local/bin/tool对非 Go 项目(Node、Python 等解释型),通常不涉及交叉编译,直接--platform多架构构建、让基础镜像自己按架构拉对应版本即可,更省心。放进 CI:GitHub Actions 示例日常最实用的是让 CI 自动出多架构镜像。官方 action 已经把 QEMU、buildx 都封装好了:name:build-and-pushon:push:tags:[v*]jobs:docker:runs-on:ubuntu-lateststeps:-uses:actions/checkoutv4-name:Set up QEMUuses:docker/setup-qemu-actionv3-name:Set up Buildxuses:docker/setup-buildx-actionv3-name:Login to registryuses:docker/login-actionv3with:registry:registry.example.comusername:${{secrets.REGISTRY_USER}}password:${{secrets.REGISTRY_PASSWORD}}-name:Build and push multi-archuses:docker/build-push-actionv6with:context:.platforms:linux/amd64,linux/arm64push:truetags:registry.example.com/myapp:${{github.ref_name}}cache-from:typegha# 用 GitHub Actions 缓存加速cache-to:typegha,modemaxcache-from/cache-to: typegha会把 BuildKit 层缓存存进 GitHub Actions 缓存,第二次构建能省掉没变的层,多架构构建本来慢,这个缓存很关键。小结exec format error的根因是镜像架构和运行机器的 CPU 架构不匹配;解法是构建成多架构镜像(manifest list),让docker pull自动选对架构。准备工作:binfmt注册 QEMU docker buildx create --driver docker-container --use(默认dockerdriver 不支持多平台)。构建命令:docker buildx build --platform linux/amd64,linux/arm64 -t ... --push .。多架构必须--push,不能--load(本地存储存不下 manifest list)。Dockerfile 里用$BUILDPLATFORM$TARGETOS/$TARGETARCH交叉编译,别把架构写死;下载预编译二进制时用$TARGETARCH拼 URL。CI 用官方setup-qemu-actionbuild-push-action,配cache-from/to: typegha提速。一句话记住:用 buildx 一次产出多架构、推成一个 tag,让每台机器各取所需——这才是彻底根治exec format error的正道。

相关新闻

LoRA在8步采样下的高动态范围保持与推理实战

LoRA在8步采样下的高动态范围保持与推理实战

最近一段时间,LoRA 相关的讨论又回到了社区热度中心。但大家讨论的焦点已经明显变了:从“怎么训出一个好看的风格 LoRA”慢慢转到了“能不能让 LoRA 在更少的采样步数下保持效果”。尤其当 MINMAX-H3 这类带着“高动态 8步加速 LoRA”标签的项目出现…

2026/9/3 20:04:22 阅读更多 →
暖风机赛元微SC92F7321程序源码解析:从选型到调试

暖风机赛元微SC92F7321程序源码解析:从选型到调试

简介:暖风机赛元微单片机SC92F7321控制程序源码包,面向家电控制与8位单片机开发者,完整实现温度检测、风速调节、安全保护等核心逻辑。包内共20个文件,压缩后大小为77KB,主要包括C语言源文件、汇编启动代码、项目头文件…

2026/9/3 20:04:22 阅读更多 →
FreeRTOS下FreeModbus移植:STM32 RS485从站实现

FreeRTOS下FreeModbus移植:STM32 RS485从站实现

简介:这是一份面向嵌入式开发者的FreeModbus移植实战资料,核心解决在FreeRTOS实时操作系统上集成FreeModbus协议栈、并实现与西门子组态屏通信的问题。资源包含50个文件,其中35个C源码和15个头文件,涵盖主库与从库的Modbus协议实现…

2026/9/3 20:03:21 阅读更多 →

最新新闻

NRF52840蓝牙键盘UI与存储设计:OLED交互和Flash参数分区落地实践

NRF52840蓝牙键盘UI与存储设计:OLED交互和Flash参数分区落地实践

NRF52840 蓝牙键盘做到这个阶段,很多人会遇到一个共同问题:BLE 通信已经通了,按键也能上报,但产品还停留在“工程师自己看得懂”的状态。真正决定使用体验的,是两块看起来不相关的模块:一块 OLED 屏幕&…

2026/9/3 20:58:04 阅读更多 →
工业级与消费级ZigBee模块怎么选?核心差异与选型清单

工业级与消费级ZigBee模块怎么选?核心差异与选型清单

打开电商平台的 ZigBee 模块页面,第一眼看到的往往是发射功率、接收灵敏度、通信距离这几个数字。很多硬件工程师和物联网项目负责人也是这样选的:参数差不多,价格差好几倍,那就选便宜的。样机测试也确实能跑通,数据传…

2026/9/3 20:58:04 阅读更多 →
AI写作工具怎么选:从Sol与Fable对比看日常创作工具的评估标准

AI写作工具怎么选:从Sol与Fable对比看日常创作工具的评估标准

推荐写作工具这件事,十次里有八次会栽在名字上。朋友问我在 Sol 和 Fable 之间怎么选,我打开搜索框一查,满屏都是公链性能:Sol 多少 TPS、共识机制怎么样、生态排第几。另一部分结果又指向完全不同的产品。同一个名字,…

2026/9/3 20:58:04 阅读更多 →
AI智能体早报:10条动态看Agent从概念走向工程化落地

AI智能体早报:10条动态看Agent从概念走向工程化落地

一份纯 Markdown 的 CSDN 技术早报类博文,结构按“速览表 -> 10 条主题解读 -> 部署与环境 -> 工程实践 -> 排查 -> 最佳实践 -> 总结”展开。AI 智能体已经不是单纯停留在发布会 PPT 上的概念了。这阵子能看到的变化是:智能体从“对话…

2026/9/3 20:57:02 阅读更多 →
MATLAB科研数据可视化:从图形对象到出版级图表

MATLAB科研数据可视化:从图形对象到出版级图表

在科研工作中,数据可视化往往决定了论文第一眼的观感。程序算出了结果,随手的plot也能展示趋势,但真正到投稿阶段,评审人首先看到的往往不是公式推导,而是图表的逻辑与美观度。图例重叠、坐标轴字体过小、色彩不区分色…

2026/9/3 20:57:02 阅读更多 →
MATLAB科研数据可视化全攻略:从底层逻辑到出版级图表

MATLAB科研数据可视化全攻略:从底层逻辑到出版级图表

科研数据可视化这件事,很多人的理解存在一个偏差:以为只要把数据丢进绘图函数,出来一张图就算完成任务。直到写论文或做汇报时,才发现图丑、不规范、看不清重点,甚至被导师或审稿人质疑数据表达能力。真正的问题不是数…

2026/9/3 20:57:02 阅读更多 →

日新闻

AI智能体辅助JS逆向:从V8环境搭建到补环境实战

AI智能体辅助JS逆向:从V8环境搭建到补环境实战

先别急着点开,这不是劝退文,而是想讲清楚一件事:用 AI 做逆向值不值得学?如果要用,怎么搭一套“V8 环境 AI 智能体”来提升效率。最近逆向圈、爬虫圈都在聊 AI Agent、AST 工程逆向、JS 逆向这些词,很多新手…

2026/9/3 0:00:29 阅读更多 →
安卓设备通过修改机型信息解锁游戏高帧率:原理、操作与风险指南

安卓设备通过修改机型信息解锁游戏高帧率:原理、操作与风险指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 0:00:29 阅读更多 →
ARM版OpenJDK 11安装部署全攻略:下载、配置与避坑指南

ARM版OpenJDK 11安装部署全攻略:下载、配置与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 0:00:29 阅读更多 →

周新闻

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

每年校招季我都会接触不少准备数据库方向笔试的同学,看到最多的状态就是:简历上写着“熟悉 MySQL”“了解索引优化”,一碰到数据库管理工程师的笔试卷,却在索引、事务、锁、备份恢复这些题目上翻车。网易这套 2018 校园招聘数据库…

2026/9/3 4:22:22 阅读更多 →
数字电路时序基石:深入理解建立时间与保持时间

数字电路时序基石:深入理解建立时间与保持时间

1. 这不是“背公式”的事:时间参数到底在约束什么你翻过数字电路教材,一定见过这两个词:建立时间(Setup Time)和保持时间(Hold Time)。它们常被并列写在触发器(Flip-Flop&#xff09…

2026/9/3 4:22:01 阅读更多 →
蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

1. 项目缘起:从赛题到超声波测距机的诞生第八届蓝桥杯单片机设计与开发国赛的题目,我至今记忆犹新。它没有直接给出一个花哨的名字,而是用“超声波测距机”这个朴实无华的功能描述,精准地勾勒出了考核的核心。对于当时备赛的我而言…

2026/9/3 4:22:59 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/3 4:17:49 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/3 4:18:56 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/3 4:21:44 阅读更多 →