如何通过GitHub Workflows用不同文件构建amd64与arm64镜像?
正确配置多平台Docker镜像构建的GitHub Workflow
问题根源
当前配置的核心问题是分开推送单个平台镜像但未生成多平台Manifest清单,同时存在以下细节问题:
- 重复执行
build-push-action且使用相同标签推送,后一次推送会覆盖前一次的元数据 - 在非对应架构的Runner上使用
load: true(比如在amd64机器上加载arm64镜像),会导致镜像架构识别异常,出现unknown/unknown - Buildx builder被限制为单个平台,无法处理跨平台构建的元数据关联
修正后的Workflow配置
jobs: docker: name: Build & Push Multi-Platform Docker Images runs-on: ubuntu-latest steps: - name: Checkout sources uses: actions/checkout@v3 - name: Docker meta id: docker_meta uses: docker/metadata-action@v4 with: images: ghcr.io/maplibre/martin tags: | type=ref,event=branch type=ref,event=tag type=sha - name: Set up QEMU uses: docker/setup-qemu-action@v2.1.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2.5.0 with: install: true - name: Login to GitHub Docker registry uses: docker/login-action@v2 if: ${{ github.actor != 'dependabot[bot]' && !github.event.pull_request.head.repo.fork }} with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} # 构建并推送所有平台镜像,自动生成多平台Manifest - name: Build and Push Multi-Platform Images uses: docker/build-push-action@v4 with: context: . # 为每个平台指定对应Dockerfile file: | linux/amd64=Dockerfile linux/arm64=arm64.Dockerfile push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.docker_meta.outputs.tags }} labels: ${{ steps.docker_meta.outputs.labels }} platforms: linux/amd64,linux/arm64
关键修改说明
- 合并构建步骤:用单个
build-push-action完成多平台构建,通过file参数为不同平台指定对应Dockerfile,避免重复推送覆盖元数据 - 移除
load参数:load仅适用于加载当前Runner架构的镜像到本地Docker daemon,跨平台场景下无需使用,直接推送即可 - 自动生成Manifest:
build-push-action默认会为多平台构建生成Manifest清单,将不同平台的镜像关联到同一标签下,解决元数据混乱问题 - 统一Buildx配置:不再限制builder为单个平台,让Buildx自动处理跨平台构建的架构适配
备选方案(矩阵构建+Manifest合并)
如果需要保留矩阵拆分构建的方式,可先推送到带平台后缀的临时标签,再合并为正式标签:
jobs: build: name: Build ${{ matrix.platform }} Docker Image strategy: fail-fast: true matrix: include: - platform: linux/amd64 file: Dockerfile tag-suffix: amd64 - platform: linux/arm64 file: arm64.Dockerfile tag-suffix: arm64 runs-on: ubuntu-latest steps: - name: Checkout sources uses: actions/checkout@v3 - name: Docker meta id: docker_meta uses: docker/metadata-action@v4 with: images: ghcr.io/maplibre/martin tags: | type=ref,event=branch,suffix=-${{ matrix.tag-suffix }} type=ref,event=tag,suffix=-${{ matrix.tag-suffix }} type=sha,suffix=-${{ matrix.tag-suffix }} - name: Set up QEMU uses: docker/setup-qemu-action@v2.1.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2.5.0 - name: Login to GitHub Docker registry if: ${{ github.actor != 'dependabot[bot]' && !github.event.pull_request.head.repo.fork }} uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and Push Platform Image uses: docker/build-push-action@v4 with: file: ${{ matrix.file }} push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.docker_meta.outputs.tags }} labels: ${{ steps.docker_meta.outputs.labels }} platforms: ${{ matrix.platform }} manifest: name: Create Multi-Platform Manifest needs: build runs-on: ubuntu-latest if: ${{ github.event_name != 'pull_request' && github.actor != 'dependabot[bot]' }} steps: - name: Docker meta id: docker_meta uses: docker/metadata-action@v4 with: images: ghcr.io/maplibre/martin tags: | type=ref,event=branch type=ref,event=tag type=sha - name: Login to GitHub Docker registry uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Create and Push Manifest uses: docker/manifest-action@v1 with: manifest: | version: 2 mediaType: application/vnd.docker.distribution.manifest.list.v2+json manifests: - mediaType: application/vnd.docker.distribution.manifest.v2+json platform: architecture: amd64 os: linux url: ${{ steps.docker_meta.outputs.tags }}-amd64 - mediaType: application/vnd.docker.distribution.manifest.v2+json platform: architecture: arm64 os: linux url: ${{ steps.docker_meta.outputs.tags }}-arm64 push: true
验证方式
推送完成后,可通过以下命令验证多平台镜像信息:
docker buildx imagetools inspect ghcr.io/maplibre/martin:latest
内容的提问来源于stack exchange,提问作者Yuri Astrakhan
相关产品推荐
相关产品推荐

