Earthly 多平台构建实战:一条命令并行构建 amd64、arm64 与 armv7 镜像
【免费下载链接】earthlySuper simple build framework with fast, repeatable builds and an instantly familiar syntax – like Dockerfile and Makefile had a baby.项目地址: https://gitcode.com/gh_mirrors/ea/earthly
对于需要同时交付多种 CPU 架构镜像的团队来说,Earthly 多平台构建是一个简单高效的选择:在 Earthfile 中用一条BUILD命令加上多个--platform标志,就能让 Earthly 并行构建 linux/amd64、linux/arm64 与 linux/arm/v7 三种架构的镜像,并在导出时自动合并成一个多架构 manifest。本文带你从零配置到实战,完成一次完整的多平台构建。
为什么选择 Earthly 做多平台镜像构建?
Earthly 是一个轻量构建框架,语法介于 Dockerfile 与 Makefile 之间,"写一次、到处运行"。它做多平台构建有三个天然优势:
- 并行执行:Earthly 自动把不同平台的构建拆成独立步骤并行运行,无需手写脚本;
- 缓存复用:基于 BuildKit 的分层缓存让相同步骤跨平台复用;
- 语法极简:不需要
docker buildx、binfmt注册脚本或 CI 矩阵配置,一个 Earthfile 搞定。
多平台构建前的准备:配置 QEMU 模拟
默认情况下,构建运行在主机自身的架构上。要执行非本机的指令(如 arm 平台上的RUN命令),需要借助 QEMU 模拟,各平台的准备工作如下:
| 运行环境 | 需要的操作 |
|---|---|
| Mac / Windows | Docker Desktop 自带 QEMU,开箱即用 |
| Apple Silicon (M1/M2) | 需在 Docker Desktop 中开启 Rosetta 模拟 |
| Linux | 需手动安装 QEMU 相关包 |
| CI(如 GitHub Actions) | 在 Job 中加入docker/setup-qemu-action步骤 |
Apple Silicon 用户:打开 Docker Desktop → Settings → Features in Development,勾选 "Use Rosetta for x86/amd64 emulation":
Linux 用户:只需一次性执行(以 Ubuntu 为例):
sudo apt-get install qemu-system binfmt-support qemu-user-static docker run --rm --privileged multiarch/qemu-user-static --reset -p yes docker stop earthly-buildkitd || true完整说明见官方文档 docs/guides/multi-platform.md。
核心写法:一条 BUILD 命令并行构建三种平台
多平台构建的关键就是重复使用BUILD --platform标志。仓库自带的 examples/multiplatform/Earthfile 展示了最典型的写法:
VERSION 0.8 all: BUILD \ --platform=linux/amd64 \ --platform=linux/arm64 \ --platform=linux/arm/v7 \ --platform=linux/arm/v6 \ +docker docker: FROM alpine:3.18 RUN uname -m CMD ["uname", "-m"] SAVE IMAGE --push earthly/examples:multiplatform+all调用一次,+docker目标就会同时执行四次,分别在四个平台上运行uname -m;- 也可以在命令行直接覆盖平台:
earthly --platform=linux/arm64 +build; - 不带任何
--platform时,构建按宿主机的原生架构进行。
如果项目就在本仓库中,克隆后可以直接体验:
cd examples/multiplatform earthly +all自动合并:多架构镜像的导出与推送
一个容易困惑的问题是:多个目标都SAVE IMAGE到同一个标签,会互相覆盖吗?
不会。只要不同目标使用完全相同的镜像标签,Earthly 在导出时会自动把它们合并成一个多平台(multi-manifest)镜像:
build-all-platforms: BUILD --platform=linux/amd64 --platform=linux/arm64 +build build: FROM alpine:3.18 SAVE IMAGE --push org/myimage:latest执行earthly --push +build-all-platforms后,Docker Registry 里得到的就是一个包含 amd64 与 arm64 两个 manifest 的镜像,docker pull时客户端会自动挑选匹配本机的架构。
⚠️注意:本地 Docker daemon 对多 manifest 镜像支持有限,因此导出到本机时,Earthly 会为每个架构额外生成带后缀的标签,如
org/myimage:latest_linux_arm64;推送到 Registry 时则是单一的多架构镜像。
进阶技巧:交叉编译实现零模拟构建
并非所有构建都必须在目标架构上执行。像 Go、Rust 这类支持交叉编译的语言,可以在本机架构上编译出目标架构的二进制,再放入对应平台的最终镜像——整个构建过程无需 QEMU,速度更快。
仓库中的 examples/multiplatform-cross-compile/Earthfile 是绝佳范例,核心思路只有两行:
build-image: ARG TARGETPLATFORM ARG TARGETARCH ARG TARGETVARIANT FROM --platform=$TARGETPLATFORM alpine:3.18 COPY \ --platform=linux/amd64 \ (+build/main --GOARCH=$TARGETARCH --VARIANT=$TARGETVARIANT) ./example/main SAVE IMAGE --push earthly/examples:multiplatform-cross-compile要点:
+build目标始终在linux/amd64上执行 Go 交叉编译,用--GOARCH/--VARIANT控制输出架构;FROM --platform=$TARGETPLATFORM决定最终镜像标记的平台;COPY --platform=linux/amd64 (+build/main ...)从 amd64 构建产物中取二进制放进目标平台镜像,+build-image目标内没有任何RUN指令,因此不需要模拟。
善用内置平台变量,让 Earthfile 更简洁
Earthly 为多平台构建提供了一组开箱即用的内置参数(完整列表见 docs/earthfile/builtin-args.md),使用前记得先ARG声明:
| 变量 | 示例值 | 用途 |
|---|---|---|
TARGETPLATFORM | linux/arm/v7 | 当前目标构建的完整平台 |
TARGETARCH | arm | 目标 CPU 架构 |
TARGETVARIANT | v7 | 目标架构变体 |
USERPLATFORM | linux/amd64 | 调用 earthly 命令的宿主机平台 |
有了这些变量,同一个+build目标就能根据平台自动切换交叉编译参数,无需为每个架构复制目标定义。
常见问题与限制
- 目前仅支持 linux 作为构建平台,Windows 容器构建尚在规划中;
WITH DOCKER的限制:包含WITH DOCKER的目标本身必须运行在宿主机原生架构上(QEMU 环境暂不支持 docker-in-docker),但其内部运行的镜像可以是任意架构:
# 正确写法:+build 运行在本机架构,内部指定镜像的平台 build: FROM earthly/dind WITH DOCKER --pull=earthly/examples:multiplatform RUN docker run --platform=linux/arm64 earthly/examples:multiplatform END- 构建失败排查:不同平台的构建步骤相互隔离,构建图(DAG)中任何一个分支失败都会终止整个构建,日志中会清晰标注失败的分支。
总结
回顾一下 Earthly 多平台构建的完整路径:
- 按需配置 QEMU / Rosetta 模拟(Apple Silicon 别忘了开 Rosetta);
- 用
BUILD --platform=linux/amd64 --platform=linux/arm64 --platform=linux/arm/v7 +target一条命令触发并行构建; - 让各目标
SAVE IMAGE到相同标签,自动合并为多架构 manifest 并推送; - 对 Go、Rust 等语言,用内置变量
TARGETARCH/TARGETVARIANT做交叉编译,彻底摆脱模拟开销。
从 examples/multiplatform 到 examples/multiplatform-cross-compile,官方示例已经覆盖了最常用的两种场景,照着修改即可快速接入自己的项目。
【免费下载链接】earthlySuper simple build framework with fast, repeatable builds and an instantly familiar syntax – like Dockerfile and Makefile had a baby.项目地址: https://gitcode.com/gh_mirrors/ea/earthly
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考