You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:10:24