GitHub has a feature called GitHub Actions that run automatic builds, tests, and other scripts whenever you make changes to a repository. One handy use case of this is automatically building and pushing Docker containers to a container registry.
GitHub’s New Container Registry
GitHub’s new container registry, called GitHub Container Registry, is a bit different than most registries like the Docker Hub. It functions as an extension of GitHub Packages, a package storage system that associates packages with their source code repositories. Packages can be built and pushed from the repository, often automatically with the help of a GitHub Actions pipeline.
GitHub Container Registry is simply adding Docker-specific compatibility to GitHub Packages, making it function like a container registry for purposes of running docker pull and other CLI commands.
You don’t need to publish to GitHub’s container registry—you can still publish to the Docker Hub from an action with some configuration. The prebuilt actions work with GHCR out of the box though, so it’s a lot simpler to set up.
How to Set Up Automatic Builds to GitHub Packages
To start, you’ll need a repository. Even if you are only publishing packages, you’ll still need a repo, because the format for GHCR is:
Set up a repo, then click on “Actions” to create a new action. Under “More Continuous Integration Workflows,” click “Publish Docker Container.”
This generates a starter template, which needs a few changes to work. First, the IMAGE_NAME variable needs to be changed to your image name.
Then, on line 39, you’ll find where it logs into GHCR.
Currently, the only supported authentication scheme is Personal Access Tokens (PATs), which isn’t great for security because they grant account-wide access. GitHub knows this, and is working on a better fix for the future, but in the meantime if you want to use GHCR from a GitHub Actions workflow, you’ll need to store a PAT in the Secrets for your repository, because obviously just pasting it in here would be horrendous.
First, you’ll need to head over to Settings > Developer Settings > Personal Access Tokens and create a new token. This token needs write:packages and delete:packages settings. Note that for some reason, selecting write packages automatically selects “Full Control Of Repositories,” which you have to uncheck.
Then, head over to the repository’s settings, and create a new secret called CR_PAT, to match the action.
Head back to the action, and click “Start Commit” to push it to the repository.
Once it’s committed, it will trigger a workflow to run and build the package. You can monitor the status of all running workflows under the “Actions” tab. Here, it failed because the default actions expects there to be tests to run, which this image didn’t have.
Once it’s successful, you should see the container in the registry, under “Packages” on the repository’s main page, or under the packages on your profile.