GitHub Container Registry: How to push Docker images to GitHub šŸ‹

The GitHub Container Registry allows you to publish or host private and public Docker images. You can find out everything you need to know in this tutorial.

With its registry service GitHub Packages, GitHub provides a way for developers to host their own Docker images directly in GitHub. In my opinion, the name of GitHub is somewhat misleading: the umbrella term for the service is GitHub Packages. It contains a number of registries. These include the Docker Registry, which has been renamed the Container Registry in order to host all types of containers.

GitHub Packages Structure

Why not use Docker Hub? šŸ‹

The Docker Hub is the first port of call when it comes to Docker images ā€“ no question about it. In the free version, however, only one private image is available to each account and the number of pulls (200 pulls per 6 hours) is also limited. And this is where the GitHub Container Registry comes into play! šŸ™‚

Push Docker Images into the GitHub Registry

To create a Docker image, we need a Docker image, which we have to create with a Dockerfile. You can create such a Dockerfile using the docker init command, for example. Once the file is available, we can build the image:

docker build -t frontend .
Enter fullscreen mode
Exit fullscreen mode

Screenshot from the Docker build process

In the next step, we need to log in to the GitHub Container Registry. To do this, we need a personal access token from GitHub.

Generate Personal Access Token (PAT)

To generate a new PAT, navigate to GitHub Settings > Developer seettings > Personal access tokens > Tokens (classic) and create a new token. You must select ā€œwrite:packagesā€ and** ā€œread:packagesā€** as the scope. You can adjust the duration of the token to your project or set it to unlimited.
Create GitHub Personal Access Token (PAT)
You should save the token, e.g. in your password manager. If you lose the token, you will have to regenerate it.

Now open a terminal on your computer and set your PAT in a variable (replace <YOUR_PAT> with your token):

# Set PAT into a variable
export GH_PAT=<YOUR_PAT>
Enter fullscreen mode
Exit fullscreen mode

To log in to the GitHub Container Registry (ghcr.io), use the following command (replace <USERNAME> with your GitHub username).

# Login to the GitHub Container Registry using your PAT
echo $GH_PAT | docker login ghcr.io -u <USERNAME> --password-stdin
Enter fullscreen mode
Exit fullscreen mode

If the PAT and your user name were correct, you should receive the message ā€œLogin Succeededā€.
Successful Docker login to the GitHub Container Registry (ghcr.io)
Next, we tag the image so that it also ends up in the correct registry. Replace <USERNAME> with your GitHub username, <IMAGE_NAME> with the desired name of the image and <TAG> with the desired tag (default: latest)

# Tag the builded docker image
docker tag frontend ghcr.io/<USERNAME>/<IMAGE_NAME>:<TAG>
Enter fullscreen mode
Exit fullscreen mode

Now we can push the image into the registry. Here you have to replace the same variables as when tagging:

docker push ghcr.io/<USERNAME>/<IMAGE_NAME>:<TAG>
Enter fullscreen mode
Exit fullscreen mode

If you have done everything correctly, you should receive such an output or no error message šŸ˜‰
GitHub Docker Regsitry: Tagging and pushing Docker images
Congratulations! You have successfully pushed your first Docker image to the GitHub registry! šŸŽ‰
GitHub Packages
On this page you now have further options, such as changing the visibility or deleting the image.

Pulling GitHub Docker Images

Of course, you can now also use your Docker images from the registry. The path is the same as for pushing:

docker pull ghcr.io/<USERNAME>/<IMAGE_NAME>:<TAG>
Enter fullscreen mode
Exit fullscreen mode

GitHub Actions Workflow for Docker Images in the GitHub Registry

Pushing Docker images manually is daft! Thatā€™s why there are CI/CD pipelines that we can implement with GitHub Actions, for example. For certain events, e.g. a new commit, we can automatically build the Docker image and publish it in the registry. In the following example, a Docker image is built and published when the frontend branch is pushed. Building and publishing is already done after the ā€œBuild and push Docker imageā€ step. However, I have left the last two steps in for the sake of completeness, as this is a workflow of one of my projects and you may also have a use case for it šŸ˜‰

In your GitHub repository, you can simply create a file under .github/workflows/cd.yml.

name: Continuous Deployment - Frontend on: push: branches: ['frontend'] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: build-and-push-image: runs-on: ubuntu-latest permissions: contents: read packages: write attestations: write steps: - name: Checkout repository uses: actions/checkout@v4 - name: Log in to the Container registry uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - name: Build and push Docker image id: push uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 with: context: . push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - name: Install SSH client run: sudo apt-get update && sudo apt-get install -y openssh-client - name: Deploy to VM env: SSH_HOST: ${{ vars.SSH_HOST }} SSH_USER: ${{ secrets.SSH_USER }} SERVER_SSH_KEY: ${{ secrets.SERVER_SSH_KEY }} IMAGE_TAG: ${{ steps.meta.outputs.tags }} run: | echo "${{ env.SERVER_SSH_KEY }}" > key.pem chmod 600 key.pem ssh -i key.pem -o StrictHostKeyChecking=no ${{ env.SSH_USER }}@${{ env.SSH_HOST }} << 'EOF' docker login ${{ env.REGISTRY }} -u ${{ github.actor }} -p ${{ secrets.MY_PERSONAL_PAT }} docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} cd ~ docker compose down frontend docker compose up -d frontend EOF # Clean up the private key.pem rm key.pem
Enter fullscreen mode
Exit fullscreen mode

And donā€™t forget: Create the used secrets and variables in the repository settings. In this case:

  • Secrets:

    • MY_PERSONAL_PAT
    • SERVER_SSH_KEY
    • SSH_USER
  • Variables:
    • SSH_HOST
      GitHub Repository: Secrets and variables

GitHub Container Registry: Conclusion

Thatā€™s it! Building and publishing Docker images in the GitHub Docker Registry or GitHub Container Registry is very similar to Docker Hub. Only the login via the GitHub PAT is a little more complicated, but also offers advantages in terms of authorisation management, etc. Will you be using the GitHub Packages Registry in the future?


Discover more from Coursity

Subscribe to get the latest posts sent to your email.

Leave a Comment

Your email address will not be published. Required fields are marked *

Discover more from Coursity

Subscribe now to keep reading and get access to the full archive.

Continue reading

Scroll to Top