Build and push docker images to ghcr.io with GitHub Actions

2022-12-28

When you host your project code on GitHub and want to release it as a docker image for deployment or just publish it, the way to go are GitHub actions. Actions are basically hooks that can start CI/DC workflows on repository events.

GitHub actions can be used to build and push images to GitHub’s Container Registry which are reachable under https://ghcr.io which is part of the package registry. The package registry is not only for docker images, it can also host quite a few other kinds of packages. In this case we’ll focus on docker images.

Prerequisites:

  • GitHub Repository
  • Basic Knowledge about GitHub actions syntax
  • Dockerfile

The GitHub Workflow

I created a workflow in my repository under .github/workflow/cd.md and added the following:

name: Continuous Delivery
on:
  push:
    branches:
      - 'main'
    tags:
      - 'v*.*.*'

jobs:
  build:
    name: Buid and push Docker image to GitHub Container registry
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read
    steps:
      - name: Checkout the repository
        uses: actions/checkout@v3

      - name: Docker Setup Buildx
        uses: docker/setup-buildx-action@v2.2.1

      - name: Docker Login
        uses: docker/login-action@v2.1.0
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push Docker images
        uses: docker/build-push-action@v3.2.0
        env:
          REGISTRY: ghcr.io
          IMAGE_NAME: ${{ github.repository }}
        with:
          context: .
          file: ./Dockerfile
          target: final
          push: true
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest

Let’s go through the important parts:

Permissions: Actions have access to the repo while running. We should always make sure by setting the permissions, that actions have the minimum access they require. See here: permissions for the github_token

Step 1–2: Checkout the code and Setup docker

Step 3: Login to GitHub Container Registry: This is where the interesting part starts. github.actor is the user that triggers the workflow. For password use secrets.GITHUB_TOKEN which is a temporary token which is automatically generated for this workflow. See here: publishing images to github-packages.

Step 4: Build and push Docker images: If the registry that you want to push to belongs to an organization then you will need to add permissions to create packages. If it lives under your own handle you don’t need to configure anything more since you are the owner already and the secrets.GITHUB_TOKEN has all the permissions granted.

The action will consume the Dockerfile and build the image up to the target build step that you can define. In docker the repository where the image will be hosted is also part of the tag. Setting the image name to the repository name will create an image with the following tag: ghcr.io/OWNER/IMAGE_NAME:latest

Read more here: pushing container images

Happy shipping \o/

Enter your instance's address


More posts like this

Environment variables in a dockerized Symfony

2023-01-02 | #cd #ci #docker #docker-compose #dotenv #env_file #symfony

I have developed a Symfony Web-Application, and it runs locally in a dockerized environment with docker-compose. This app is going to be deployed to production as a docker container. In production the handling of environment variables and how they are passed to the container during development is different. 12 Factor App A few points from the 12factor methodology: III. Config: Store config in the environment since env vars are easy to change between deploys without changing any code X.

Continue reading 


Goodbye Jekyll, hello Hugo

2022-12-27 | #blog #cd #git #github #github-actions #hugo #jekyll

I started this blog in March 2013 when I was working for ImagineEasy when I had a few ideas to write down on how I’d work with Doctrine Repositories. I still like the idea, but I’d probably do it a bit different today. The blog and also how I’d work with doctrine. At the time Jekyll was the way to handle a static file blog. Since then, again, a few things have changed.

Continue reading 