生産性向上ブログ

継続的な生産性向上を目指すエンジニアのためのブログ

GitHub Container Registry 入門

github.blog

9/1 に GitHub Container Registry がパブリックベータとして公開されました。GitHub が提供する Docker レジストリサービスです。

この記事では、GitHub Container Registry についていろいろ調べたり動かしたりした内容をまとめます。

目次

注意事項

GitHub Container Registry は、この記事の執筆時点(2020/09/03)ではまだパブリックベータの段階です。将来的に機能や仕様などが変更になる可能性があるのでご注意ください。

背景

既存の Docker レジストリサービスとの関係性について簡単にまとめ、GitHub Container Registry の公開によってなにが変わるかを説明します。

Docker Hub と GitHub Container Registry

これまで、ユーザーが Docker イメージを公開・共有するための Docker レジストリサービスとしては、Docker 社が提供する Docker Hub がメジャーでした。特に、無料でイメージを public に公開できるという点で、他の Docker レジストリにはない強みがありました。

しかし、最近になって Docker Hub は規約変更により複数の新たな制限の追加を発表していました。

www.docker.com

↑は、11/1 から無料プランだと Docker イメージが 6 ヶ月以上 pull または push もないイメージは削除されるようになるという話です。

www.docker.com

↑ は、11/1 から Docker Hub の pull 回数に rate limit が設けられる話です。無料プランだと、認証なしで 6 時間に 100 回まで、認証ありで 6 時間に 200 回までです。

これらの規約変更は、Docker Hub が増え続けるユーザーベースに対して、インフラをスケールさせ無料のサービスを持続できるようにするためとしています。とはいえ、やはりユーザーとしては利便性が落ちます。

このタイミングで、GitHub Container Registry が発表されたことは、とてもタイムリーに感じます。GitHub Container Registry には、今のところ Docker Hub に追加されたような制限は特に見当たりません。

一方、Docker 社側からも GitHub Container Registry の使い方についてのブログ記事が、GitHub Container Registry の発表に合わせてすぐ公開されています。

www.docker.com

なので、たまたまタイミングが合ったというよりは、GitHub 社と Docker 社の間でなんらかの協力体制が事前にできていると考えるのが妥当なのではと思われます。(といっても推測でしかないですが)

GitHub Packages と GitHub Container Registry

GitHub Container Registry は、GitHub Packages に新たに追加された機能という位置づけになっています。GitHub Packages はパッケージホスティングサービスで、これまではそちらを Docker レジストリとして利用することが可能でした。つまり、現時点では従来の Packages と新しい GitHub Container Registry の 2 つの Docker レジストリが存在することになります。

GitHub Container Registry は、以下のような点が従来の Packages と異なります。

従来の Packages GitHub Container Registry
イメージの保存先 リポジトリに紐づく organization やユーザーアカウントに紐づく
権限 リポジトリの権限と同じ イメージごとに設定できる
認証なしでの public イメージの pull 不可能 可能
ドメイン docker.pkg.github.com
/OWNER/REPOSITORY/IMAGE_NAME
ghcr.io/OWNER/IMAGE_NAME

全体的に、GitHub Container Registry のほうが使いやすくなっていると思います。特に、従来の Packages では、public イメージの pull に認証が必要だったことが Docker Hub からの移行を妨げる要因として大きかったです。なので、GitHub Container Registry の公開によって、Docker Hub からの移行は多くなるのではと思われます。

料金

パブリックベータ期間中は、GitHub Container Registry は public/private どちらでも無料です。(なぜか従来の Packages の Docker レジストリも無料になるようなことが書いてあります)

パブリックベータ終了後は、GitHub Packages と同じ料金体型になります。現在の Packages は、public は完全無料で、private はストレージとデータ転送量に対して課金されます。契約プランごとに以下の無料枠が存在します。

プラン ストレージ データ転送量
Free 500MB 1GB
Pro 2GB 10GB
Team 2GB 10GB
Enterprise Cloud 50GB 100GB

無料枠を超えると、ストレージとデータ転送量はそれぞれ以下の料金がかかります。

  • ストレージ:$0.25/GB
  • データ転送量:$0.50/GB

AWS ECR や Google Cloud Container Registry あたりと比べると、少し割高ですかね。

データ転送量は、push に関しては無料、pull に関しては GitHub Actions の GitHub が提供するランナー上からは無料です。要は、GitHub Actions 外からの pull によるデータ転送量のみ課金されるようです。

organization での GitHub Container Registry の有効化

organization で GitHub Container Registry を利用できるようにするためには、organization の Settings → Member privileges から以下の設定を変更する必要があります。Public と Private それぞれで利用可能にするか設定できます。

f:id:miya-jan:20200903052902p:plain

ちなみに、個人のユーザーアカウントでは特に設定しなくても GitHub Container Registry を利用可能です。

試してみる

実際に GitHub Container Registry を動かしてみます。この記事の例では、筆者個人のユーザーアカウントにイメージを push します。

パーソナルアクセストークンの作成

Docker イメージを GitHub Container Registry に push するためには認証が必要なので、パーソナルアクセストークンを作成します。パーソナルアクセストークンには、次のスコープが必要です。

  • read:packages: イメージのダウンロードやメタデータの取得に必要
  • write:packages: イメージのアップロードとメタデータの読み書きに必要
  • delete:packages: イメージの削除に必要

ユーザーアカウントの Settings → Developer settings → Personal access tokens から、以下の設定で作成します。

f:id:miya-jan:20200903053023p:plain

パーソナルアクセストークンを作成したら、シェルで CR_PAT という環境変数に設定します。

$ export CR_PAT=<PERSONAL_TOKEN_TOKEN>

イメージの push

まずは、docker login で認証してみます。miyajan のところは各自の GitHub ユーザー名です。

$ echo $CR_PAT | docker login ghcr.io -u miyajan --password-stdin
Login Succeeded

適当なイメージを Docker Hub から持ってきて、GitHub Container Registry に push してみます。

$ docker pull hello-world
...
$ docker tag hello-world ghcr.io/miyajan/hello-world
$ docker push ghcr.io/miyajan/hello-world
The push refers to repository [ghcr.io/miyajan/hello-world]
9c27e219663c: Layer already exists
latest: digest: sha256:90659bf80b44ce6be8234e6ff90a1ac34acbeb826903b02cfa0da11c82cbc042 size: 525

無事成功すると、個人アカウントの Packages に表示されます。

f:id:miya-jan:20200903053123p:plain

ちなみに、同じイメージ・タグ名で再 push による上書きは可能でした。

イメージの権限変更

イメージのページを開き、右の "Edit package" と書かれたドロップダウンから "Package settings" をクリックすると、権限などの設定画面が表示されます。

f:id:miya-jan:20200903053145p:plain:w300 f:id:miya-jan:20200903053202p:plain

"Invite teams or people" から招待したメンバーには、以下のようなロール指定のドロップダウンが表示されます。(ちなみに、チームを招待できるのは organization のイメージだけです)

f:id:miya-jan:20200903054402p:plain:w300

ロールはそれぞれ次のような権限を持ちます。

  • Read: イメージのダウンロード、メタデータの取得
  • Write: イメージのアップロードとダウンロード、メタデータの読み書き
  • Admin: イメージのアップロードとダウンロード、メタデータの読み書き、権限変更

また、"Danger Zone" にある "Make public" からイメージを public に変更できます。一度 public に変更すると、private には戻せないので注意してください。

認証なしで public イメージの pull

前述の手順でイメージを public にして、認証なしでイメージが pull できることを確認してみます。1

$ docker logout ghcr.io
Removing login credentials for ghcr.io
$ docker pull ghcr.io/miyajan/hello-world
Using default tag: latest
latest: Pulling from miyajan/hello-world
Digest: sha256:90659bf80b44ce6be8234e6ff90a1ac34acbeb826903b02cfa0da11c82cbc042
Status: Image is up to date for ghcr.io/miyajan/hello-world:latest
ghcr.io/miyajan/hello-world:latest

無事、認証なしで pull できました。

イメージの削除

"Package settings" の "Delete this package" からイメージを削除できます。

公式ドキュメントを見ると、

To prevent confusion and build problems, GitHub permanently reserves a package's name and version number. Even if an entire package is deleted, you cannot reuse the deleted package name in any repository owned by the same account.

と一度削除したイメージと同じ名前やバージョンは永続的に利用できなくなるようなことが書かれているのですが、現時点では同じ名前でイメージを再 push できました。従来の Packages の記述を誤って書いてしまっているのか、バグなのかは不明です。

GitHub Actions から GitHub Container Registry を使う上での注意点

現時点で GitHub Container Registry は、GitHub Actions でワークフロー実行時にデフォルトで提供される GITHUB_TOKEN という秘密情報に対応していません。なので、パーソナルアクセストークンを作成して、Secrets に設定して使う必要があるので注意が必要です。

将来的に GITHUB_TOKEN をサポートする予定はありそうです。

もちろん、public なイメージを pull するだけであればトークンは必要ありません。

Packages から GitHub Container Registry への移行

従来の Packages から GitHub Container Registry へイメージを移行するには、CLI で再 push すれば OK です。以下のようになるはずです。

$ docker pull docker.pkg.github.com/OWNER/REPOSITORY/IMAGE_NAME:VERSION
$ docker tag docker.pkg.github.com/SOURCE_OWNER/SOURCE_REPOSITORY/SOURCE_IMAGE_NAME:VERSION ghcr.io/TARGET_OWNER/TARGET_IMAGE_NAME:VERSION
$ docker push ghcr.io/OWNER/IMAGE_NAME:VERSION

まとめ

GitHub Container Registry について、背景や試し方、設定変更方法などを書きました。最新情報については、公式ドキュメントを確認してください。

所感としましては、やはり public イメージを認証なしで pull できるようになってだいぶ実用度が上がったと思います。public イメージは完全無料なのもやはり強いです。GitHub で権限まわりが完結するのも強いです。とにかく GitHub 強い。

信頼度の高そうな Docker レジストリはとてもありがたく、今後どんどん活用していきたいです。


  1. Docker CLI のバージョンによっては docker logout 時に Warning が表示されますが、ログアウトには成功します。関連