GitHub CLIの一時的なトークンを使ってGitHub Packagesからdockerイメージをpullするお手軽な方法
背景
開発時にメンバーが同じDockerイメージを使ってトラブル時に簡単に問題の再現を共有できるように、雑にCIするときにGitHub PackagesにDockerイメージをpushするようにしています。
どうせCIではdocker buildしていますからね。突然Dockerイメージがビルド出来なくなったら悲惨なのでCIではどうせビルドする必要があります。それならpushしても大した時間コストにはならないので雑に行って問題ありません。
GitHub ActionsでのCIのステップの一部
push
以下のように仕込んでやって、 bake定義を雑に書いておけば、後はビルド時にtagがついて毎回pushされます。
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/bake-action@v6
with:
files: |
./docker-bake.hcl
cwd://${{ steps.meta.outputs.bake-file }}
push: true
env:
CACHIX_AUTH_TOKEN: "${{ secrets.CACHIX_AUTH_TOKEN }}"
cleanup
GitHub Packagesを無料枠で収めるために雑に古いイメージを消去する必要があります。
以下のステップを日本時間で6時に毎日実行するようにしています。
- uses: dataaxiom/ghcr-cleanup-action@v1
with:
exclude-tags: master # masterタグは除外
keep-n-tagged: 10 # タグ付きイメージは最新10個保持
keep-n-untagged: 10 # タグなしイメージは最新10個保持
delete-ghost-images: true
delete-partial-images: true
delete-orphaned-images: true
厳密にイメージを管理するならもう少し真面目に考える必要があるのでしょうが、とりあえず我々にはこれで十分です。
問題
ここに挙げているdockerイメージをpullする方法を尋ねられました。
考えてみるとリポジトリがprivateだし、 GitHub Enterprise Cloud なのは混乱の原因です。
検索して出てくる既存の解決策
とりあえずClaudeに聞いてみたら、 PATとしてトークンを新しく払い出すという方法が提案されました。
永続的なトークンをむやみに作成したくないし、トークン生成というそれぞれのユーザのアカウントに依存するGUIの作業を他の人に依頼したくないです。
解決策
GitHub CLI からトークンを生成する方法で解決を試みます。
以下の手順で私の環境ではpullすることに成功しました。
YOUR_GITHUB_USERNAME
は自分のGitHubユーザ名に、
YOUR_ORG/YOUR_PACKAGE
は実際のorganization名とパッケージ名に置き換えてください。
gh auth refresh -s read:packages
gh auth token | docker login ghcr.io --username YOUR_GITHUB_USERNAME --password-stdin
docker pull ghcr.io/YOUR_ORG/YOUR_PACKAGE
解説
gh auth token
でトークンは生成できます。しかしデフォルトの状態では403エラーでpullできません。
gh auth status
で確認すると、以下のような表示になりました。
github.com
✓ Logged in to github.com account ncaq (/home/ncaq/.config/gh/hosts.yml)
- Active account: true
- Git operations protocol: https
- Token: gho_************************************
- Token scopes: 'gist', 'read:org', 'repo', 'workflow'
トークンのスコープにpackages
関連が含まれていないことがわかります。
なのでgh auth refresh -s read:packages
でトークンにスコープを追加してやれば問題解決します。もちろん認証をリフレッシュする必要があるので実行する時はWebブラウザなどでログインする作業が必要です。