How to build your Docker image using Multi-Arch to support ARM64 (M1 Macbook)
Using GitHub Actions workflow to automate a multi-arch (amd64/arm64) build for docker images and seamless continuous integration with help from ChatGPT.

Well, Docker is supposed to be very portable. It allows you to seamlessly run containers on any platform, using Docker for Linux and/or Docker Desktop for macOS and Windows. However, for some quiet time, all the underlying technology I’ve been using has been the same — platform wise. Where the architecture of the server and/or local machine has been linux/amd64
. As well as, the GitHub Actions runners have been the same as well— linux/amd64
. Checkout this GitHub repo for more details
Recently, I’ve come across a problem while running containers from a custom-built image on a linux/arm64
platform. It made me wonder how other images were working just fine, like postgres:11
on linux/arm64
and linux/amd64
platforms.
Troubleshooting
Scenario:
Running a docker container with a bash script as the entry point of a custom-built image for linux/amd64
on an arm64 architecture.
Result:
Often results in such an error: exec/bin/bash: exec format error
After some research, with attempts to fix the entrypoint.sh
by adding #!/bin/bash
at the top of the bash script. Which I already had. I turned to ChatGPT for help.

So to make sure of your architecture start by:
uname -m


and you are looking for aarch64
, even if your output is x86_64
you should still follow along.
Why?
Because simply that’s the goal of Docker, how portable it can be. This made me realize that multi-arch building is a must.
Building containers to be supported by all machines seamlessly regardless of the underlying architecture.
Setting up local buildx Docker Build for amd64/arm64
Before setting up, to be able to build docker images using multi-arch locally you need buildx
, from here. If you are running Docker Desktop — macOS, windows buildx is installed by default.
buildx
allows for multi-arch builds by adding a customized field platform
to the docker build
command.
You can now locally build your image for linux/amd64
and linux/arm64
:
click here for more info
docker buildx build --platform linux/amd64,linux/arm64 .
Setting up GitHub Actions workflow to automate Docker Build for amd64/arm64 with CI
You will need the same setup to be applied at the GitHub runner. Using GitHub workflow file to instruct the runner into building the docker image with specific platforms.
There are predefined GitHub Actions for your workflow file that makes the process seamless.
The following workflow file’s actions are basically:
- Checkout
- QEMU [ Hardware emulator]
- Setup Docker Buildx [Needs to be setup on linux—ubuntu]
- Login, build, and push with custom platforms
Checkout
Checkout the repository in github action runner
- name: Checkout
uses: actions/checkout@v3
QEMU and Setup Docker Buildx
# Setup hardware emulator using QEMU
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
# Setup Docker Builderx for multi-arch images
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
Login, build, and push with custom platforms
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
# Use github secrets to add your PTA
password: ${{ secrets.__YOUR__PERSONAL__GITHUB__TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64, linux/arm64 # Add other platforms here
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}
Putting it all together in a GitHub workflow file: