Building Multi-CPU Architecture Docker Images for ARM and x86 (3): Building in GitHub Action CI

Jacky Jiang
ITNEXT
Published in
2 min readJan 21, 2022

--

Photo by Richy Great on Unsplash

In “Building Multi-CPU Architecture Docker Images for ARM and x86 (1): The Basics”, we covered the general workflow of building multi-arch Docker images with buildx/buildkit. In this article, we will cover how to get it running on GitHub Action CI.

Runner Environment

Using ubuntu-latest runner environment will be the easiest option to get your multi-arch pipeline running on Github action CI. e.g. You can specify your job runner environment by:

jobs:  
build-docker-images:
name: Build Docker Images
runs-on: ubuntu-latest

Set up QEMU

Buildkit uses QEMU to emulate different target platforms when building Docker images for different target platforms on one machine. To setup/install QEMU, we can use `docker/setup-qemu-action`:

- name: Set up QEMU        
uses: docker/setup-qemu-action@v1

Setup Buildx

To setup / install buildx, we can use `docker/setup-buildx-action`:

- name: Set up Docker Buildx        
uses: docker/setup-buildx-action@v1

Complete Example of Build Multi-arch Images & Push to `GitHub Packages` Registry

jobs:  
build-docker-images:
name: Build Docker Images
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to GitHub Package Registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Build & Push Docker image
run: docker buildx build -t ghcr.io/${{ github.repository_owner }}/myimage:${GITHUB_SHA} -f [path to Dockerfile] --push --platform=linux/arm64,linux/amd64 [path to build context]

Retag & Copy Multi-arch Images to Docker Hub

In the CI pipeline, we often push docker images to the CI platform provided registry for testing & verification. But, eventually, we will want to retag & copy the multi-arch Docker image in GitHub Packages Registry to a production registry. e.g. Docker Hub.

With multi-arch images, we cannot use the old workflow to retag & push docker image to a different registry using docker tag & docker push command as they only work with one image rather than multiple images behinds one manifest registry entry.

To solve this issue, we can use regclient . Its command syntax is very simple. To retag & copy the image that we built & pushed to the GitHub Packages registry in the previous example and push to the Docker hub, we can run:

- name: Login to Docker Hub        
env:
DH_TOKEN: ${{ secrets.DOCKER_HUB_PASSWORD }}
run: docker login -u my-docker-hub-username -p ${DH_TOKEN}
- name: Re-tag & Push Docker Image to Docker Hub
run: |
# make config.json avaiable to regclient in docker container
chmod +r $HOME/.docker/config.json
# Run regclient in docker image
docker container run --rm --net host \
-v regctl-conf:/home/appuser/.regctl/ \
-v $HOME/.docker/config.json:/home/appuser/.docker/config.json \
regclient/regctl:v0.3.9 image copy ghcr.io/${{ github.repository_owner }}/myimage:${GITHUB_SHA} docker.io/xxxx/myimage:v1

--

--