Docker 多平台构建(buildx)实战:一条命令产出 amd64 + arm64 镜像

发布时间:2026/10/24 4:06:36
Docker 多平台构建(buildx)实战:一条命令产出 amd64 + arm64 镜像

Apple Silicon 普及后,"在 Mac 上构建的镜像跑不了 Linux 服务器"成了新痛点。本文详解 Docker buildx 的安装、配置、多平台构建全流程,以及 CI/CD 中的最佳实践。


一、为什么需要多平台构建

1.1 问题的根源

Docker 镜像是平台相关的。一个在 x86_64 机器上构建的镜像,包含的是 x86_64 架构的二进制文件,无法在 ARM64 机器(如 Apple M1/M2、AWS Graviton)上运行。

# 在 x86 机器上构建 docker build -t myapp . # 推到 ARM 服务器上运行 → 报错 docker: Error response from daemon: image with reference myapp was found but does not match the specified platform: wanted linux/arm64, actual: linux/amd64

1.2 传统解法 vs buildx

传统做法:分别在 x86 和 ARM 机器上构建,然后手动打不同 tag。

# x86 机器 docker build -t myapp:amd64 . docker push myapp:amd64 # ARM 机器 docker build -t myapp:arm64 . docker push myapp:arm64

buildx 做法:一条命令同时构建多平台镜像,自动合并为 manifest list。

docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest --push .

二、安装与启用 buildx

2.1 检查是否已安装

docker buildx version # 输出:github.com/docker/buildx v0.12.0 ...

Docker Desktop 和 Docker Engine 23.0+ 已内置 buildx。如果未安装:

# Linux mkdir -p ~/.docker/cli-plugins curl -SL https://github.com/docker/buildx/releases/download/v0.12.0/buildx-v0.12.0.linux-amd64 \ -o ~/.docker/cli-plugins/docker-buildx chmod +x ~/.docker/cli-plugins/docker-buildx

2.2 创建并启用 builder

# 查看现有 builder docker buildx ls # 创建新的 builder(支持多平台) docker buildx create --name multiarch --use # 启动 builder docker buildx inspect --bootstrap # 验证支持的平台 docker buildx inspect --bootstrap | grep Platforms # 输出:linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

三、多平台构建实战

3.1 基础多平台构建

# Dockerfile FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build EXPOSE 3000 CMD ["node", "dist/main.js"]
# 构建并推送到 Registry(必须 --push 或 --load) docker buildx build \ --platform linux/amd64,linux/arm64 \ -t myregistry.com/myapp:latest \ --push \ .

关键参数:

  • --platform:指定目标平台,逗号分隔
  • --push:构建后直接推送到 Registry
  • --load:构建后加载到本地 Docker(只能单平台)
  • -t:镜像 tag

3.2 本地测试多平台镜像

# 构建 arm64 镜像并加载到本地(用于测试) docker buildx build \ --platform linux/arm64 \ -t myapp:arm64-test \ --load \ . # 运行测试 docker run --rm myapp:arm64-test

3.3 使用缓存加速

# 本地缓存 docker buildx build \ --platform linux/amd64,linux/arm64 \ -t myapp:latest \ --cache-from type=local,src=/tmp/buildx-cache \ --cache-to type=local,dest=/tmp/buildx-cache \ --push \ . # Registry 缓存(推荐 CI/CD) docker buildx build \ --platform linux/amd64,linux/arm64 \ -t myapp:latest \ --cache-from type=registry,ref=myregistry.com/myapp:cache \ --cache-to type=registry,ref=myregistry.com/myapp:cache,mode=max \ --push \ .

四、Dockerfile 多平台适配

4.1 基础镜像选择

# 使用官方多平台基础镜像 FROM node:18-alpine # 支持 amd64 + arm64 # 避免使用单平台镜像 FROM some-image:latest # 可能只有 amd64

4.2 平台特定依赖

# 根据平台安装不同依赖 FROM golang:1.21-alpine # 安装平台特定的包 RUN apk add --no-cache \ ${TARGETPLATFORM:+musl-dev} \ gcc # 使用 TARGETARCH 变量 ARG TARGETARCH RUN echo "Building for ${TARGETARCH}"

4.3 交叉编译 Go 应用

FROM golang:1.21-alpine AS builder ARG TARGETOS ARG TARGETARCH WORKDIR /app COPY . . # 交叉编译 RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ go build -o /app/server . FROM alpine:3.18 COPY --from=builder /app/server /usr/local/bin/ CMD ["server"]
# 一条命令构建多平台 docker buildx build \ --platform linux/amd64,linux/arm64 \ -t myapp:latest \ --push \ .

4.4 交叉编译 Rust 应用

FROM rust:1.70-alpine AS builder ARG TARGETARCH RUN apk add --no-cache musl-dev WORKDIR /app COPY . . # 根据架构设置目标 RUN if [ "$TARGETARCH" = "arm64" ]; then \ rustup target add aarch64-unknown-linux-musl && \ cargo build --release --target aarch64-unknown-linux-musl; \ else \ cargo build --release; \ fi FROM alpine:3.18 ARG TARGETARCH COPY --from=builder /app/target/${TARGETARCH:+aarch64-unknown-linux-musl/}release/myapp /usr/local/bin/ CMD ["myapp"]

五、CI/CD 中的多平台构建

5.1 GitHub Actions

name: Build Multi-Arch Image on: push: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and Push uses: docker/build-push-action@v5 with: context: . push: true platforms: linux/amd64,linux/arm64 tags: ghcr.io/${{ github.repository }}:latest cache-from: type=gha cache-to: type=gha,mode=max

5.2 GitLab CI

build-multiarch: stage: build image: docker:24-dind services: - docker:24-dind script: - docker buildx create --use - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - > docker buildx build --platform linux/amd64,linux/arm64 -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --push .

5.3 Jenkins Pipeline

pipeline { agent any stages { stage('Build Multi-Arch') { steps { script { docker.withRegistry('https://registry.example.com', 'credentials-id') { sh ''' docker buildx create --use docker buildx build \ --platform linux/amd64,linux/arm64 \ -t registry.example.com/myapp:${BUILD_NUMBER} \ --push \ . ''' } } } } } }

六、常见问题与解法

6.1 构建报错:no match for platform

现象:

ERROR: Multiple platforms feature is currently not supported for docker driver.

原因:使用了默认的 docker driver,不支持多平台。

解法:

# 创建使用 docker-container driver 的 builder docker buildx create --name multiarch --driver docker-container --use docker buildx inspect --bootstrap

6.2 构建速度慢

原因:QEMU 模拟 ARM 指令,速度比原生慢 5-10 倍。

解法:

  1. 使用交叉编译代替 QEMU 模拟(Go/Rust/C 等编译型语言)
  2. 启用缓存(见 3.3 节)
  3. 使用 GitHub Actions 的 setup-qemu-action + setup-buildx-action

6.3 本地无法运行多平台镜像

现象:

docker buildx build --platform linux/amd64,linux/arm64 -t myapp . docker run myapp # 报错

原因:--load 只能加载单平台镜像。

解法:

# 方案一:指定单平台加载 docker buildx build --platform linux/amd64 -t myapp --load . # 方案二:构建后直接推送,不在本地运行 docker buildx build --platform linux/amd64,linux/arm64 -t myapp --push .

6.4 基础镜像不支持多平台

现象:某个基础镜像只有 amd64 版本。

解法:

  1. 寻找官方多平台替代镜像
  2. 自己构建多平台基础镜像
  3. 使用 TARGETPLATFORM 条件安装不同依赖

七、最佳实践清单

  1. 基础镜像选官方多平台版本(如 node:18-alpine、golang:1.21)
  2. 编译型语言用交叉编译,避免 QEMU 模拟
  3. CI/CD 中启用缓存,加速重复构建
  4. 测试时加载单平台镜像,推送时用多平台
  5. 使用 --cache-to type=registry在团队间共享缓存
  6. 定期清理 builder 缓存:docker buildx prune

八、总结

场景命令
本地单平台测试docker buildx build --platform linux/arm64 --load .
推送多平台镜像docker buildx build --platform linux/amd64,linux/arm64 --push .
CI/CD 构建GitHub Actions + docker/build-push-action
加速构建--cache-from type=registry + 交叉编译

Docker buildx 让多平台构建从"分别在多台机器上构建"变成"一条命令搞定"。掌握它,就能轻松应对 Apple Silicon、AWS Graviton、阿里云倚天等多架构环境。