Date posted: 06 Jan 2021, 3 minutes to read

GitHub Container Registry

I wanted to use the GitHub Container Registry to host an image for me and had some issues setting things up. To save me some time the next time I need this, and hopefully for someone else as well, I wanted to document how this process works.

Image of a lighthouse at night

Photo by Evgeni Tcherkasski on Unsplash

Beta period

During the beta, the container registry will be free to use. Open-source and public repositories are always entirely free to use, but private repositories will fall under the standard billing rates for GitHub Packages after the beta is over. The free tier of that includes 500 MB of storage and 1 GB of transfer every month.

Enable GitHub Container Registry

Currently, the registry is in Beta, so you’ll need to enable the beta feature on your profile or on the organization level you want to use it on. To do so, go to your profile (or organization) and go to Feature preview where you can toggle the feature. You’ll notice a new ‘Packages’ tab on you profile page as well.

Location to find the preview settings

Preparing to push image to the registry

Currently the only way to authenticate with GitHub Container Registry is to use a GitHub Personal Access Token (PAT). GitHub already knows this is an issue because the PAT can be used in the entire account it is created and will change that later.
For now the advisory is to create a specific PAT with only rights to the registry and use that.

These are the scopes you need to enable for the PAT:

  • read:packages scope to download container images and read their metadata.
  • write:packages scope to download and upload container images and read and write their metadata.

If you want to delete the packages, also use this scope:

  • delete:packages scope to delete container images.

Personal Access Token Creation

Using a GitHub workflow to build and push an image

To push a new image from a workflow, use the complete example below.

The steps used are as follows:

  1. Get the source code with the docker file and anything you need to build the image. ``` yaml
    • uses: actions/checkout@v1 ```
  2. Build the image ``` yaml
    • name: Build the Docker image run: docker build -t ghcr.io/«ACCOUNT NAME»/«IMAGE NAME»:«VERSION» . ```
  3. The normal docker build step where I am tagging the image with the tag I want to push to the registry ``` yaml
    • name: Build the Docker image run: docker build -t ghcr.io/«ACCOUNT NAME»/«IMAGE NAME»:«VERSION» . ```
  4. Authenticate with the GitHub Container Registry Using the recommended by GitHub) for safety ``` yaml
    • name: Setup GitHub Container Registry run: echo “$” | docker login https://ghcr.io -u $ –password-stdin ```
  5. The normal docker push step to push the container ``` yaml
    • name: push to GitHub Container Registry run: docker push ghcr.io/«ACCOUNT NAME»/«IMAGE NAME»:«VERSION» ```

Full workflow example

name: Build and Push Docker container

on: 
  push:
    branches:
      - main

jobs:
  build-and-push:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1

    - name: Build the Docker image
      run: docker build -t ghcr.io/<<ACCOUNT NAME>>/<<IMAGE NAME>>:<<VERSION>> .

    - name: Setup GitHub Container Registry
      run: echo "$" | docker login https://ghcr.io -u $ --password-stdin

    - name: push to GitHub Container Registry
      run:  docker push ghcr.io/<<ACCOUNT NAME>>/<<IMAGE NAME>>:<<VERSION>>

Secret names

Do note that I am using secrets.GH_PAT to inject the PAT token I’m using into the workflow. You cannot use GITHUB as a prefix for the secret name, so you need to change that. The secrets user interface doesn’t tell you about that in a great way, which I have sent GitHub feedback on through the GitHub Community.

Consuming the new image

By default the images are kept behind a login, so if you want to make the image publicly available you need to do that for each package.

Keep the image behind a login

To use the image behind the login, you’ll need to authenticate with the registry first:

echo "$env:GH_PAT" | docker login https://ghcr.io -u USERNAME --password-stdin

Enable the public registry

Note: this is a one way trip: it cannot be made private after making it publicly available

To change this setting: go to the package and to its settings: Package settings

And make the image publicly available: Make the image public