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

如何通过GitHub Actions将GHCR指定Commit SHA的镜像复制到ACR并迁移所有标签与元数据

GitHub Actions 同步 GHCR 镜像到 ACR(含全标签+元数据)

解决思路

你之前用Docker拉取推送的方式拿不到对应SHA的所有标签,核心问题是Docker本身没法直接查询镜像SHA关联的标签列表。这里用GitHub Packages API查标签,搭配skopeo工具(比Docker更适合跨注册表同步,还能完整保留元数据)来搞定,不用本地拉取镜像,效率更高。

完整工作流代码

name: Sync GHCR to ACR
on:
  workflow_dispatch:
    inputs:
      commit_sha:
        description: '要同步的镜像对应的Commit SHA(完整SHA-256)'
        required: true
      ghcr_image:
        description: 'GHCR镜像全名(比如 ghcr.io/your-account/your-app)'
        required: true
      acr_registry:
        description: 'ACR注册表地址(比如 youracr.azurecr.io)'
        required: true
      acr_repo:
        description: 'ACR里的目标镜像路径(比如 your-account/your-app)'
        required: true

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - name: 安装 skopeo
        run: |
          sudo apt update && sudo apt install -y skopeo

      - name: 登录GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: 登录ACR
        uses: azure/docker-login@v1
        with:
          login-server: ${{ inputs.acr_registry }}
          username: ${{ secrets.ACR_USERNAME }}
          password: ${{ secrets.ACR_PASSWORD }}

      - name: 查GHCR中对应SHA的所有标签
        id: fetch_tags
        run: |
          # 调用GitHub Packages API筛选出关联该SHA的标签
          TAGS=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
            "https://api.github.com/users/${{ github.repository_owner }}/packages/container/${{ inputs.ghcr_image }}/versions" | \
            jq -r --arg SHA "${{ inputs.commit_sha }}" '.[] | select(.metadata.container.config.Digest | contains($SHA)) | .name')
          echo "tags=$TAGS" >> $GITHUB_OUTPUT

      - name: 同步镜像+所有标签到ACR
        run: |
          SOURCE="${{ inputs.ghcr_image }}@sha256:${{ inputs.commit_sha }}"
          # 先同步带SHA的基础镜像
          skopeo copy --all docker://$SOURCE docker://${{ inputs.acr_registry }}/${{ inputs.acr_repo }}@sha256:${{ inputs.commit_sha }}
          # 给ACR镜像逐个添加标签
          for TAG in ${{ steps.fetch_tags.outputs.tags }}; do
            skopeo copy docker://$SOURCE docker://${{ inputs.acr_registry }}/${{ inputs.acr_repo }}:$TAG
          done

关键细节说明

  1. 为什么用skopeo?
    它直接在注册表之间复制镜像,不用拉到本地,还能完整保留镜像的元数据(环境变量、入口点、LABEL等),比docker pull/push省心多了。

  2. 怎么拿到对应SHA的标签?
    通过GitHub的Packages API遍历镜像的所有版本,筛选出元数据里Digest包含目标Commit SHA的条目,提取这些条目的标签名。注意输入的SHA得是完整的SHA-256值,不然匹配可能出问题。

  3. 权限配置

    • GHCR登录:用默认的GITHUB_TOKEN就行,只要工作流有packages:read权限(默认已开启)。
    • ACR登录:得在GitHub仓库的Secrets里存好ACR_USERNAME(ACR的管理员账号或服务主体用户名)和ACR_PASSWORD(对应密码/密钥)。

注意点

  • 如果你的镜像是多架构的(比如amd64+arm64),--all参数会同步所有架构的镜像层,别漏加。
  • 要是标签列表为空,说明输入的SHA没有匹配到任何GHCR镜像,得检查SHA或者镜像名是否正确。
  • 可以给循环加个判断,比如if [ -n "$TAG" ]; then ...; fi,避免空标签导致错误。

内容的提问来源于stack exchange,提问作者Zefferno

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 04:55:28