If you love to code , you must be familiar with github, most of us likely store/backup or even work via github, collaboration and easy code sharing make it become a must tool for the one who love to code. GHA or github actions are definition of job task to do if something happen push, tag, release, etc in your repo. In this writing we specifically building docker image with it, this guide will assuming that we already got a repo at github.

First we add a simple file called docker-image-build.yml, place the file at .github/workflows/docker-image-build.yml. You can add it via github web or via terminal, git add, git commit. Then we add a simple job, that is build docker image when im pushing.

name: Build Docker Image

on:
  push:
    branches: [ "master" ]
    tags: [ 'v*.*.*' ]

  pull_request:
    branches: [ "master" ]

env:
  # Use docker.io for Docker Hub if empty
  REGISTRY: ghcr.io
  # github.repository as <account>/<repo>
  IMAGE_NAME: ${ { github.repository } }

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Setup QEMU
        uses: docker/setup-qemu-action@v2

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

      - name: Log into registry env.REGISTRY
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v2
        with:
          registry: ${ { env.REGISTRY } }
          username: ${ { github.actor } }
          password: ${ { secrets.GITHUB_TOKEN } }

      - name: Docker metadata
        id: metaid
        uses: docker/metadata-action@v4
        with:
          images: ${ { env.REGISTRY/$env.IMAGE_NAME } }
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern=version
            type=semver,pattern=major.minor

      - name: Build and push Docker image
        id: build-and-push
        uses: docker/build-push-action@v3
        with:
          context: .
          push: ${ { github.event_name != 'pull_request' } }
          tags: ${ { steps.meta.outputs.tags } }
          platforms: linux/amd64,linux/arm64

More details about the jobs:

  • This actions will trigger when something pushed the master branch and when a PR issued

    on:
    push:
    branches: [ "master" ]
    tags: [ 'v*.*.*' ]
    
    pull_request:
    branches: [ "master" ]
  • The job will run using ubuntu-latest, ubuntu-latest itself is github actions predefined container there is also macos-latest, windows-latest, etc.

    on:
    push:
    branches: [ "master" ]
    tags: [ 'v*.*.*' ]
    
    pull_request:
    branches: [ "master" ]
  • Set some variables to be used entire workflows, this setup is for github container registry ghcr.io. Depends on personal preferences this part can be ignored, you will see why later.

    env:
    REGISTRY: ghcr.io
    IMAGE_NAME: ${ { github.repository } }
  • This 3 combo jobs practically describe itself about what are they doing, chekout repo, setup qemu, and setup buildx.

      - name: Checkout repository
        uses: actions/checkout@v3
    
      - name: Setup QEMU
        uses: docker/setup-qemu-action@v2
    
      - name: Setup Docker buildx
        uses: docker/setup-buildx-action@v2

The next part is docker login, this is the part where can be tricky sometimes. Remember the REGISTRY and IMAGE_NAME env setup earlier? This is where it can be used.

      - name: Log into registry $env.REGISTRY
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v2
        with:
          registry: ${ { env.REGISTRY } }
          username: ${ { github.actor  } }
          password: ${ { secrets.GITHUB_TOKEN } }

essentially this job translate to this:

      - name: Log into registry ghcr.io
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${ { github.actor } } #your github user name
          password: ${ { secrets.GITHUB_TOKEN } } #your token

With dockerhub version:

      - name: Login to Docker Hub
        uses: docker/login-action@v2
        if: github.event_name != 'pull_request'
        with:
          username: ${ { secrets.DOCKERHUB_USERNAME } }
          password: ${ { secrets.DOCKERHUB_TOKEN } }

As docker default login is always to dockerhub we doesn't need to set registry. As registry beside dockerhub and ghcr.io, there is also quay.io, ecr, or even your personal hosted registry if your registry exposed to public.

  • This part will define our image url and tag such as ghcr.io/github-username/docker-image-name:docker-image-tag, there is many custom setup but just let it be, as this setup mostly work for many cases

    - name: Docker metadata
        id: metaid
        uses: docker/metadata-action@v4
        with:
          images: ${ { env.REGISTRY/$env.IMAGE_NAME } }
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={ { version } }
            type=semver,pattern={ { major } }.{ { minor } }
  • The last part is building the image, yay . This job will take metadata from previous steps, but also you can override manually and skip the metadata part tags: ghcr.io/github-username/repo-name:some-tag. But it pretty inconvenient, except you just want the only one single image, no versioning or other tags.

      - name: Build and push Docker image
        id: build-and-push
        uses: docker/build-push-action@v3
        with:
          context: .
          push: ${ { github.event_name != 'pull_request' } }
          tags: ${ { steps.meta.outputs.tags } }
          platforms: linux/amd64,linux/arm64

sources:

Previous Post Next Post

Add a comment