前言
隨著 ARM 架構處理器(如 Apple M1/M2、AWS Graviton)的普及,開發者經常需要建置同時支援 x86_64 和 ARM64 架構的 Docker 映像。Docker Buildx 是 Docker 官方提供的 CLI 擴充工具,讓我們能夠輕鬆地建置多平台映像。
Buildx 概述
Docker Buildx 是基於 BuildKit 的進階建置工具,提供以下主要功能:
- 多平台建置:單一指令同時建置多種 CPU 架構的映像
- 快取優化:支援本地與遠端快取,加速建置流程
- 並行建置:同時建置多個目標平台
- 進階輸出格式:支援 OCI 標準格式與多種輸出方式
確認與啟用 Buildx
檢查 Buildx 版本
首先確認系統已安裝 Buildx:
輸出範例:
1
| github.com/docker/buildx v0.11.2 9872040
|
查看現有 Builder
輸出範例:
1
2
3
4
5
| NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
default docker
default default running 23.0.6 linux/amd64, linux/amd64/v2, linux/amd64/v3
desktop-linux docker
desktop-linux desktop-linux running 23.0.6 linux/amd64, linux/amd64/v2, linux/amd64/v3
|
建立 Builder 實例
建立支援多平台的 Builder
使用 docker-container 驅動建立新的 Builder 實例:
1
2
3
4
| docker buildx create --name multiplatform-builder \
--driver docker-container \
--bootstrap \
--use
|
參數說明:
--name:指定 Builder 名稱--driver docker-container:使用容器驅動,支援多平台建置--bootstrap:立即啟動 Builder 實例--use:設定為預設使用的 Builder
檢視 Builder 詳細資訊
1
| docker buildx inspect multiplatform-builder
|
輸出範例:
1
2
3
4
5
6
7
8
9
10
| Name: multiplatform-builder
Driver: docker-container
Last Activity: 2024-10-07 08:30:00 +0000 UTC
Nodes:
Name: multiplatform-builder0
Endpoint: unix:///var/run/docker.sock
Status: running
Buildkit: v0.12.2
Platforms: linux/amd64, linux/amd64/v2, linux/arm64, linux/arm/v7, linux/arm/v6
|
支援的平台
Buildx 透過 QEMU 模擬器支援多種平台架構:
| 平台標識 | 說明 |
|---|
linux/amd64 | 64 位元 x86 架構(Intel/AMD) |
linux/arm64 | 64 位元 ARM 架構(Apple M1/M2、AWS Graviton) |
linux/arm/v7 | 32 位元 ARM 架構(Raspberry Pi 2/3) |
linux/arm/v6 | 32 位元 ARM 架構(Raspberry Pi 1/Zero) |
linux/386 | 32 位元 x86 架構 |
linux/ppc64le | IBM Power 架構 |
linux/s390x | IBM Z 系列架構 |
多平台建置指令
基本多平台建置
1
2
3
4
| docker buildx build \
--platform linux/amd64,linux/arm64 \
-t myapp:latest \
.
|
建置並載入到本地
注意:載入到本地 Docker 時只能選擇單一平台:
1
2
3
4
5
| docker buildx build \
--platform linux/amd64 \
-t myapp:latest \
--load \
.
|
建置並輸出為 tar 檔案
1
2
3
4
5
| docker buildx build \
--platform linux/amd64,linux/arm64 \
-t myapp:latest \
--output type=oci,dest=./myapp-multiarch.tar \
.
|
推送到 Registry
推送到 Docker Hub
1
2
3
4
5
6
| docker buildx build \
--platform linux/amd64,linux/arm64,linux/arm/v7 \
-t username/myapp:latest \
-t username/myapp:v1.0.0 \
--push \
.
|
推送到私有 Registry
1
2
3
4
5
| docker buildx build \
--platform linux/amd64,linux/arm64 \
-t registry.example.com/myapp:latest \
--push \
.
|
檢視多平台映像資訊
1
| docker buildx imagetools inspect username/myapp:latest
|
輸出範例:
1
2
3
4
5
6
7
8
9
10
11
12
| Name: docker.io/username/myapp:latest
MediaType: application/vnd.oci.image.index.v1+json
Digest: sha256:abc123...
Manifests:
Name: docker.io/username/myapp:latest@sha256:def456...
MediaType: application/vnd.oci.image.manifest.v1+json
Platform: linux/amd64
Name: docker.io/username/myapp:latest@sha256:ghi789...
MediaType: application/vnd.oci.image.manifest.v1+json
Platform: linux/arm64
|
QEMU 模擬器
安裝 QEMU 模擬器
在 Linux 系統上執行跨平台建置需要 QEMU:
1
| docker run --privileged --rm tonistiigi/binfmt --install all
|
檢查已安裝的模擬器
1
| docker run --privileged --rm tonistiigi/binfmt
|
移除模擬器
1
| docker run --privileged --rm tonistiigi/binfmt --uninstall qemu-*
|
Dockerfile 多平台技巧
Buildx 會自動注入平台相關變數:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| FROM --platform=$BUILDPLATFORM golang:1.21 AS builder
# 自動注入的變數
ARG TARGETPLATFORM
ARG TARGETOS
ARG TARGETARCH
WORKDIR /app
COPY . .
# 使用變數進行交叉編譯
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
go build -o /app/myapp .
FROM alpine:3.18
COPY --from=builder /app/myapp /usr/local/bin/
CMD ["myapp"]
|
平台特定安裝
1
2
3
4
5
6
7
8
9
10
11
12
| FROM alpine:3.18
ARG TARGETARCH
RUN case ${TARGETARCH} in \
"amd64") ARCH="x86_64" ;; \
"arm64") ARCH="aarch64" ;; \
*) ARCH=${TARGETARCH} ;; \
esac && \
wget -O /usr/local/bin/tool \
"https://example.com/releases/tool-${ARCH}" && \
chmod +x /usr/local/bin/tool
|
CI/CD 整合
GitHub Actions 範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| name: Build Multi-Platform Image
on:
push:
branches: [main]
tags: ['v*']
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
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 Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and Push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
username/myapp:latest
username/myapp:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
|
GitLab CI 範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| build-multiplatform:
image: docker:24
services:
- docker:24-dind
variables:
DOCKER_BUILDKIT: 1
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker buildx create --use --name gitlab-builder
script:
- docker buildx build
--platform linux/amd64,linux/arm64
--push
-t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
-t $CI_REGISTRY_IMAGE:latest
.
|
常見問題排解
建置快取
使用 Registry 作為快取:
1
2
3
4
5
6
7
| docker buildx build \
--platform linux/amd64,linux/arm64 \
--cache-from type=registry,ref=username/myapp:cache \
--cache-to type=registry,ref=username/myapp:cache,mode=max \
--push \
-t username/myapp:latest \
.
|
清理 Builder
1
2
3
4
5
| # 清理建置快取
docker buildx prune
# 移除 Builder 實例
docker buildx rm multiplatform-builder
|
總結
Docker Buildx 大幅簡化了多平台映像的建置流程。透過本文的介紹,您應該能夠:
- 建立並管理 Buildx Builder 實例
- 建置支援多種 CPU 架構的 Docker 映像
- 在 Dockerfile 中處理平台差異
- 將多平台建置整合到 CI/CD 流程中
參考資料