[自分用メモ]GitHub Container Registry から Docker Hub への効率的なコンテナイメージ同期方法

AIX、UNIX、LinuxContainerSoftware

コンテナイメージをGitHub Container Registryから Docker Hubへ自動的に同期する方法について解説します。Docker Hubの新しいレート制限に対応するための実践的なアプローチです。

はじめに

2025年4月からDocker Hubのpullレート制限が変更され、特に認証なしユーザーや個人アカウントでの利用に影響が出ています。この記事では、GitHub Container Registry (ghcr.io)をメインのレジストリとして使いながら、Docker Hub (docker.io)との同期を自動化する方法を紹介します。

Docker Hubの新しいレート制限

2025年4月から適用されたDocker Hubのpullレート制限は以下の通りです:

ユーザータイプ6時間あたりのpullレート制限
Business (認証済み)無制限
Team (認証済み)無制限
Pro (認証済み)無制限
Personal (認証済み)200回
未認証ユーザーIPv4アドレスまたはIPv6 /64サブネットごとに100回

このレート制限により、特に頻繁にイメージをpullする開発環境や自動化されたCI/CDパイプラインでは問題が発生する可能性があります。

GitHub Container Registryを活用する理由

GitHub Container Registry (ghcr.io)には以下のメリットがあります:

  • GitHub Actionsと緊密に統合されている
  • プライベートリポジトリでも無料で利用可能
  • レート制限がDocker Hubより緩やか
  • GitHub認証情報をそのまま利用可能

同期の仕組み

今回紹介する方法では、以下のフローでコンテナイメージを管理します:

  1. GitHub Actionsでコンテナイメージをビルド
  2. ビルドしたイメージをGitHub Container Registryにプッシュ
  3. container-registry-sync-actionを使ってDocker Hubに同期

これにより、Docker Hubのpullレート制限を回避し、ghcr.ioからpullすることが出来るのでレート制限を回避出来る。また、既存のDocker Hub依存のシステムにも対応できます。

実装方法

1. レジストリへのログイン設定

まず、GitHub ActionsワークフローでDocker HubとGitHub Container Registryの両方にログインするための設定を行います:

steps:
  - name: Login to DockerHub
    uses: regclient/actions/regctl-login@main
    with:
      registry: docker.io
      username: ${{ secrets.DOCKERHUB_USERNAME }}
      password: ${{ secrets.DOCKERHUB_TOKEN }}

  - name: Login to GHCR
    uses: regclient/actions/regctl-login@main
    with:
      registry: ghcr.io
      username: ${{ github.actor }}
      password: ${{ secrets.GITHUB_TOKEN }}

2. コンテナレジストリ同期アクションの設定

次に、container-registry-sync-actionを使って、GitHub Container Registryから Docker Hubにイメージを同期します:

- name: sync images
  uses: it-bens/container-registry-sync-action@main
  with:
    sourceRepository: 'ghcr.io/${{ github.repository_owner }}/${{ steps.image-name.outputs.image_name }}'
    loginToSourceRepository: 'true'
    sourceRepositoryUsername: ${{ github.actor }}
    sourceRepositoryPassword: ${{ secrets.GITHUB_TOKEN }}
    targetRepository: '${{ github.repository_owner }}/${{ steps.image-name.outputs.image_name }}'
    loginToTargetRepository: 'true'
    targetRepositoryUsername: ${{ secrets.DOCKERHUB_USERNAME }}
    targetRepositoryPassword: ${{ secrets.DOCKERHUB_TOKEN }}

この設定では:

  • sourceRepository: 同期元のリポジトリ(ghcr.io)
  • targetRepository: 同期先のリポジトリ(docker.io)
  • 各レジストリの認証情報

同期ステータスについて

/usr/bin/rm /home/runner/.regctl/bin/regctl
regctl was downloaded from https://github.com/regclient/regclient/releases/latest/download/regctl-linux-amd64 to /home/runner/.regctl/bin
/usr/bin/chmod +x /home/runner/.regctl/bin/regctl
regctl version latest was installed to /home/runner/.regctl/bin/regctl
/home/runner/.regctl/bin/regctl version
VCSTag:     v0.8.3
VCSRef:     ba184b305aaad55b40bf517d06e4d8d1afd35bf9
VCSCommit:  ba184b305aaad55b40bf517d06e4d8d1afd35bf9
VCSState:   clean
VCSDate:    2025-04-23T19:16:08Z
Platform:   linux/amd64
GoVer:      go1.24.2
GoCompiler: gc
/home/runner/.regctl/bin/regctl registry login ghcr.io -u *** --pass-stdin
time=2025-04-26T05:57:15.966Z level=WARN msg="Changing login user for registry" orig=githubactions new=*** host=docker.io
time=2025-04-26T05:57:15.966Z level=WARN msg="Changing login password for registry" host=docker.io
/home/runner/.regctl/bin/regctl registry login -u *** --pass-stdin
time=2025-04-26T05:57:16.309Z level=WARN msg="Changing login user for registry" orig=githubactions new=*** host=docker.io
time=2025-04-26T05:57:16.309Z level=WARN msg="Changing login password for registry" host=docker.io
3 tags were found in the source repository.
3 tags match the tags filter in the source repository.
The following tags will be copied from ghcr.io/***/unbound to ***/unbound: 1.23.0, 1.23.0rc2, latest
/home/runner/.regctl/bin/regctl image copy ghcr.io/***/unbound:1.23.0 ***/unbound:1.23.0
time=2025-04-26T05:57:17.403Z level=WARN msg="Changing login user for registry" orig=githubactions new=*** host=docker.io
time=2025-04-26T05:57:17.403Z level=WARN msg="Changing login password for registry" host=docker.io
docker.io/***/unbound:1.23.0
/home/runner/.regctl/bin/regctl image copy ghcr.io/***/unbound:1.23.0rc2 ***/unbound:1.23.0rc2
time=2025-04-26T05:57:28.651Z level=WARN msg="Changing login user for registry" orig=githubactions new=*** host=docker.io
time=2025-04-26T05:57:28.651Z level=WARN msg="Changing login password for registry" host=docker.io
docker.io/***/unbound:1.23.0rc2
/home/runner/.regctl/bin/regctl image copy ghcr.io/***/unbound:latest ***/unbound:latest
time=2025-04-26T05:57:40.169Z level=WARN msg="Changing login user for registry" orig=githubactions new=*** host=docker.io
time=2025-04-26T05:57:40.169Z level=WARN msg="Changing login password for registry" host=docker.io
docker.io/***/unbound:latest

一応、github actionにも書かれていますが、同期済みのイメージについては自動的にスキップされるとのことです。

メリットと注意点

メリット

  • Docker Hubのレート制限問題を解決(ghcr.ioからのpullに置き換え)
  • GitHub Actions内で完結する自動化
  • GitHub Container Registryの利点を活かしつつDocker Hubの互換性も確保

注意点

  • GitHub Actionsの使用時間が若干増加する
  • シークレット管理が必要
  • イメージの同期タイミングに注意

まとめ

GitHub Container Registryをメインのレジストリとして活用しつつ、Docker Hubへの自動同期を実現することで、レート制限問題を解決しながら両方のエコシステムを活用できます。container-registry-sync-actionを使えば、追加のビルドステップなしで効率的に同期が可能だと思います。

この記事を書いた人

kometchtech

うつ病を患いながら、IT業界の末席にいるおっさんエンジニア。科学計算をしたことがないのに、HPC分野にお邪魔している。興味のある分野で学習したことをblogにまとめつつ、うつ病の経過症状のメモも置いておく日々。じつはRouterboard User Group JPの中の人でもある。 Amazon欲しいものリスト / Arm板を恵んでくれる人募集中

kometchtechをフォローする

コメント

タイトルとURLをコピーしました