Authorizing GitHub Container Registry

1. Docker unauthorized errors

If you ever get unauthorized error messages from docker-compose pull or docker login, this is likely due to an (mis|un)configured or expired GitHub Packages token. This post will quickly walk you through the steps to resolve this error.

Here’s what the error will look like with docker-compose:

$ docker-compose pull
Pulling andrewhoog.com-web ... error

ERROR: for andrewhoog.com-web  Get https://ghcr.io/v2/ahoog42/andrewhoog.com/andrewhoog.com/manifests/1.0.1: unauthorized
ERROR: Get https://ghcr.io/v2/ahoog42/andrewhoog.com/andrewhoog.com/manifests/1.0.1: unauthorized

and if using docker pull:

$ docker pull ghcr.io/ahoog42/andrewhoog.com/andrewhoog.com:1.1.15
Error response from daemon: Get https://ghcr.io/v2/ahoog42/andrewhoog.com/andrewhoog.com/manifests/1.1.15: unauthorized

2. Docs on GitHub Packages auth

Per the GitHub documentation about support for packages:

To use or manage a package hosted by a package registry, you must use a personal access token (classic) with the appropriate scope, and your personal account must have appropriate permissions.

So while I’d prefer to use the newer personal access tokens which are more granular, it does not seem it’s supported yet. If you create the GitHub token (classic) in the UI, though, it will automatically add the repo permission which is overly permissive. In GitHub’s documentation on working with the container registry, there’s a note with a nice workaround:

As a workaround, you can select just the write:packages scope for your personal access token (classic) in the user interface with this url: https://github.com/settings/tokens/new?scopes=write:packages.

3. (Re)generate a GitHub Container Registry token

So, you can generate a token with write_packages permission only and then copy the token to your clipboard. Finally, run the following commands on the host your are trying to access the container from:

Note: put an extra space in front of your export command so the token doesn’t get written to your shell history!

$  export CR_PAT=<copied-token-here>

Then execute the docker-login command with the token:

$ echo $CR_PAT | docker login ghcr.io -u ahoog42 --password-stdin

Finally, you can can try to pull the container again and it should work (at least the auth part)! In my example:

$ docker pull ghcr.io/ahoog42/andrewhoog.com/andrewhoog.com:1.1.16