Contents

x86 機器 build arm Docker Image 方法

最近要 build ARM Image 在 Raspberry Pi 上部署,但在 Raspberry Pi 上直接 build 的時間非常久。調查後發現 x86 機器可以透過 QEMU 模擬 ARM 架構來 build Image,大幅縮短開發週期。

為什麼需要在 x86 上 build ARM Image?

Raspberry Pi 使用 ARM 架構(ARMv7/ARMv8),而開發機通常是 x86_64。若直接在 Raspberry Pi 上 build Image:

  • 編譯速度極慢(Pi 的 CPU 效能遠低於開發機)
  • CI/CD Pipeline 難以整合(Runner 通常是 x86)

在 x86 機器上 build ARM Image,可以利用開發機的高效能 CPU,再將 Image 部署到 Pi 上執行。

方法一:安裝 QEMU + docker buildx

步驟 1:安裝 QEMU 跨架構模擬支援

1
2
3
sudo apt-get update && sudo apt-get install -y --no-install-recommends \
  qemu-user-static \
  binfmt-support

qemu-user-static 讓 Linux kernel 能夠透過 QEMU 執行 ARM 二進位檔案。

步驟 2:啟用 binfmt_misc 支援

Docker Desktop(Mac/Windows)已內建此支援。Linux 上需要執行:

1
docker run --privileged --rm tonistiigi/binfmt --install all

確認支援的平台:

1
docker buildx ls

步驟 3:建立 buildx Builder

1
2
3
4
5
# 建立新的 builder instance
docker buildx create --name mybuilder --use

# 啟動 builder
docker buildx inspect --bootstrap

步驟 4:Build ARM Image

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Build ARM64 Image(適用 Raspberry Pi 4)
docker buildx build --platform linux/arm64 -t myimage:arm64 .

# Build ARMv7 Image(適用 Raspberry Pi 3/4 32-bit 系統)
docker buildx build --platform linux/arm/v7 -t myimage:armv7 .

# 同時 Build 多個平台並推送到 Registry
docker buildx build \
  --platform linux/amd64,linux/arm64,linux/arm/v7 \
  -t your-registry/myimage:latest \
  --push \
  .

--push 會在 build 完成後直接推送到 Container Registry,並自動建立多架構 Manifest。

方法二:使用 docker manifest 建立多架構 Image

若已分別 build 好不同架構的 Image,可以手動建立 Multi-arch Manifest:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 分別 build 各架構
docker build -t your-registry/myimage:amd64 .
docker buildx build --platform linux/arm64 -t your-registry/myimage:arm64 .

# 推送各架構 Image
docker push your-registry/myimage:amd64
docker push your-registry/myimage:arm64

# 建立 manifest list
docker manifest create your-registry/myimage:latest \
  your-registry/myimage:amd64 \
  your-registry/myimage:arm64

# 推送 manifest
docker manifest push your-registry/myimage:latest

之後執行 docker pull your-registry/myimage:latest,Docker 會根據當前機器架構自動拉取對應的 Image。

在 Raspberry Pi 上拉取 Image

1
2
3
4
5
# 在 Raspberry Pi 上,直接 pull,Docker 自動選擇 arm64 版本
docker pull your-registry/myimage:latest

# 確認 Image 架構
docker inspect your-registry/myimage:latest | grep Architecture

應用場景

  • Raspberry Pi 部署:在 CI/CD Pipeline(x86 Runner)build ARM Image,自動部署到 Raspberry Pi 叢集
  • ARM 雲端服務器:AWS Graviton、Azure Ampere 等 ARM 雲端機器,可在 x86 開發機上 build Image 後部署
  • 多架構發布:開源軟體通常需要同時支援 x86 和 ARM,使用 buildx 一次 build 多架構版本

參考資料