docker 27+已原生集成buildx,但必须显式创建并启动支持多平台的builder实例,且构建时须用--platform明确指定linux/amd64,linux/arm64等完整平台标识,否则默认仅构建宿主机架构。

直接用 docker buildx build 就能构建多架构镜像,但不配置 builder、不指定 --platform、Dockerfile 里硬编码 GOARCH,必然失败——不是报 no valid drivers found,就是本地 docker images 只看到一个架构。
builder 没创建或没启用,buildx 就是摆设
新装 Docker Desktop(Mac/Windows)或 Linux 上的 Docker,docker buildx ls 往往只显示 default 且状态为 inactive。这不是版本问题,是 buildx 驱动根本没加载。
- 运行
docker buildx create --use --name mybuilder --platform linux/amd64,linux/arm64创建 builder;--platform必须显式列出所有目标架构,不能只写一个 - 再执行
docker buildx inspect --bootstrap启动它;如果提示qemu-user-static未注册,补一句docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - 确认生效:
docker buildx ls输出中mybuilder状态应为running,PLATFORMS列包含linux/amd64,linux/arm64
--platform 不写全,buildx 就只构建当前机器架构
即使 builder 支持多平台,docker buildx build 也不会自动推断目标。你在 M1 Mac 上跑,不加 --platform,默认只出 linux/arm64;在 Intel 服务器上跑,只出 linux/amd64。
- 必须显式写
--platform linux/amd64,linux/arm64;不能简写成amd64,arm64,也不能漏掉linux/前缀 - 多架构场景下基本必须用
--push;--load只支持单架构,且只会加载当前宿主机匹配的那个,docker images看不到其他架构 - 命令示例:
docker buildx build --platform linux/amd64,linux/arm64 -t yourname/app --push .
Dockerfile 里硬编码 GOARCH,会导致 exec format error
Go 二进制跨架构运行失败,90% 是因为编译阶段用了错误的 GOARCH。buildx 在每个平台上下文中会自动注入 TARGETARCH 变量,你该用它,而不是写死。
- ✅ 正确写法:在
FROM golang:1.22-alpine AS builder阶段加ARG TARGETARCH,然后RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -o app . - ❌ 错误写法:
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .——这会让 arm64 构建也产出 amd64 二进制,推到 ARM 容器里直接报exec format error - 如果项目依赖 cgo(比如 SQLite),
CGO_ENABLED=0会失效,必须提前在 builder 镜像中安装对应架构的交叉工具链,或换用tonistiigi/cc类 builder 镜像
CI/CD 中容易忽略的 platform 注册和缓存配置
GitHub Actions、GitLab CI 等环境里,docker/setup-buildx-action 默认不启用多平台,buildx inspect 可能只返回空列表。
- GitHub Actions 中必须显式传参:
with: { platforms: 'linux/amd64,linux/arm64' } - 本地开发时
--cache-from/--cache-to可能被忽略,但在 CI 中加一句--cache-from type=registry,ref=your-registry/cache:latest能显著提速 - 构建上下文(build context)别打包整个
node_modules或vendor;用.dockerignore排除无关文件,否则上传耗时 + 缓存失效
最常被跳过的其实是 docker buildx inspect --bootstrap 这一步——builder 创建了,但没启动,后续所有 build 都静默降级为单架构,而错误日志里甚至不报错,只默默产出一个架构的镜像。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











