🌊

GitHub Container Registryへのdocker loginでGitHub CLIの認証情報を利用する

2022/08/05に公開

GitHub Container RegistryはGitHubを利用して開発している場合は大変便利なコンテナレジストリです。例えばプライベートなイメージにアクセスできる権限をOrganizationやTeam単位で簡単に制御できたり、GitHub Actions経由でのイメージのプッシュも簡単に行うことができます。

気になる点があるとすれば、イメージをdocker pullするためにはGitHub Container Registryへのdocker loginが必要ですが、その際にPrivate Access Token(PAT)が要求されてしまう点です。

https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-to-the-container-registry

開発プロセスの中でチームメンバー全員にPATの発行と管理を強いることになるのはできるだけ避けたいです。

そんな中、迂回策の一つとしてGitHub CLIの認証情報を利用してdocker loginする方法がexperimentalではあるもののGitHub CLIのIssueで紹介されていたため、日本語でも紹介します。

https://gist.github.com/mislav/e154d707db230dc882d7194ec85d79f6
https://github.com/cli/cli/issues/5150

手順の全体像

  1. PATH配下に docker-credential-gh ファイルを作成しシェルスクリプトを実行可能にする
  2. ~/.docker/config.jsonにクレデンシャルヘルパーの設定を追加する
  3. docker login ghcr.io

PATH配下に docker-credential-gh ファイルを作成しシェルスクリプトを実行可能にする

以下のファイルを作成し、実行権限を付与しておきます。

/usr/local/bin/docker-credential-gh
#!/bin/bash
# This "docker-credential-gh" utility should exist an as executable somewhere in PATH.
#
# Dependencies: gh
#
set -e

cmd="$1"
if [ "erase" = "$cmd" ]; then
  cat - >/dev/null
  exit 0
fi
if [ "store" = "$cmd" ]; then
  cat - >/dev/null
  exit 0
fi
if [ "get" != "$cmd" ]; then
  exit 1
fi

host="$(cat -)"
host="${host#https://}"
host="${host%/}"
if [ "$host" != "ghcr.io" ] && [ "$host" != "docker.pkg.github.com" ]; then
  exit 1
fi

token="$(gh config get -h github.com oauth_token)"
if [ -z "$token" ]; then
  exit 1
fi

printf '{"Username":"%s", "Secret":"%s"}\n' "$(gh config get -h github.com user)" "$token"

~/.docker/config.jsonにクレデンシャルヘルパーの設定を追加する

dockerが利用可能になっている場合 ~/.docker/config.json があるはずですので、そこに以下の内容を加筆します。

~/.docker.config.json
{
        ~ 省略 ~
+       "credsStore": "desktop",
+       "credHelpers": {
+               "docker.pkg.github.com": "gh",
+               "ghcr.io": "gh"
+       }
}

credHelpersのキーにレジストリのドメインを指定し、値にプログラムのサフィックスを指定すると、docker engineは指定したレジストリの資格情報の取得で docker-credential-<value> を実行しようとします。それを利用し ghcr.io へのログインには1の工程で作成したスクリプトを実行させます。

https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/login/#credentials-store

docker login

ghcr.ioにログインします。 Login Succeeded と表示されれば成功です。

$ docker login ghcr.io
Authenticating with existing credentials...
Login Succeeded

これでイメージのpull/pushができるはずです。

補足

元々はGitHub CLIで gh auth configure-docker のようなコマンドを提供し、上記の手順をGitHub CLI側で行うための議論が進められていました。
しかし gh の実行ユーザーが必ずPATHへの書き込みができると仮定するのは安全ではないとし議論が止まっています。

GitHubで編集を提案

Discussion