Publish containers to Github Container Registry with Github Actions

Alessandro Vozza
Cooking with Azure
Published in
2 min readSep 7, 2020

--

With the recent announcements from Docker about sunsetting of unused Docker images from the Docker Hub and Azure Container Registry offering public anonymous pull in private preview only it’s high time to look for an alternative public container registry to host some images I need to build and host (quay.io offers free unlimited hosting starting at 15$/mo).

In a recent blog post Github introduced the Github Container Registry to replace Github packages (which, surprinsingly, require authentication to pull images), which offers unauthenticated pulls for packages (in this case, docker containers).

You can find an example on how I build and host containers on Github by looking at this Github action: https://github.com/ams0/openhack-containers/blob/master/.github/workflows/poi_ghcr_publish.yml; the only necessary step is to create a Github Token (visit https://github.com/settings/tokens) with delete:packages, read:packages, repo, write:packages capabilities and store it in the repository as a secret called CR_PAT.

name: Publish poi container to GitHub Registry

on:
push:
paths:
- "src/poi/**"

env:
# TODO: Change variable to your image's name.
IMAGE_NAME: poi

jobs:
# Push image to GitHub Packages.
# See also https://docs.docker.com/docker-hub/builds/
ghr_push:
runs-on: ubuntu-latest
if: github.event_name == 'push'

steps:
- uses: actions/checkout@v2

- name: Build poi image
run: docker build src/poi/ --file dockerfiles/Dockerfile_3 --tag $IMAGE_NAME

- name: Log into GitHub Container Registry
# TODO: Create a PAT with `read:packages` and `write:packages` scopes and save it as an Actions secret `CR_PAT`
run: echo "${{ secrets.CR_PAT }}" | docker login https://ghcr.io -u ${{ github.actor }} --password-stdin

- name: Push poi image to GitHub Container Registry
run: |
IMAGE_ID=ghcr.io/${{ github.repository }}/$IMAGE_NAME

# Change all uppercase to lowercase
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')

# Strip git ref prefix from version
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')

# Strip "v" prefix from tag name
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')

# Use Docker `latest` tag convention
[ "$VERSION" == "master" ] && VERSION=latest

echo IMAGE_ID=$IMAGE_ID
echo VERSION=$VERSION

docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
docker push $IMAGE_ID:$VERSION

Images are stored as private by default, so you need to go to https://github.com/<user>?tab=packages and manually set them to public (I can’t find a way using the API yet).

--

--

Alessandro Vozza
Cooking with Azure

Full time Cloud Pirate, software engineer at Microsoft, public speaker, community organiser and mentor. Opinions are mine’s, facts are facts.