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: