How to Automate Building Multi-Architecture Container Images

KC
4 min readNov 20, 2022

Since many developers are moving local environment to Apple M1 (ARM-based silicon) and AWS has provided ARM-based Graviton2 instances that offer the best performance per cost-instance, multi-architecture (amd64, arm64) container images should be considered. This article goes through how to build multi-architecture images in your local environment and automate them through GitHub Actions and AWS CodeBuilds.

https://unsplash.com/photos/eo5jK8Mmz68

## User Story

- As a: Developers build container images manually with a single architecture
- I want to: have multi-architecture images to support both amd64 and arm64, and automate the image build procedure as a CI pipeline.
- So that: the developer can easily deliver the container to the multi-architecture environment

## Easy Win

docker buildx ls shows what emulators are installed in your environment. If you don’t see any lists, you can install Docker build on your machine.

Buildx enables many powerful build features such as providing built-in support for building multi-platform. All build execute via buildx run with Moby/Buildkit builder engine which is running on an extra container.

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
15166d7ffcf9 moby/buildkit:buildx-stable-1 "buildkitd" 3 weeks ago Up 4 hours buildx_buildkit_mybuilder0

docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
mybuilder * docker-container
mybuilder0 unix:///var/run/docker.sock running linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
desktop-linux docker

## Building image with Buildx

https://docs.docker.com/build/building/multi-platform/#getting-started

Build the Dockerfile with buildx, passing the list of architectures as a comma-separated list to build for. for instance

docker buildx build -platform linux/amd64,linux/arm64 \
-t cloudacode/simple-test:latest - push .

Buildx will pull two different versions, one containing x86 binaries and another containing arm64 binaries, and then run shell binary on each of them.

Since docker buildx does not support multi-platform images locally issue, you need to build container images one by one if you don’t want to push the image to the registry straightway.

for arch in amd64 arm64; do docker buildx build -t cloudacode/simple-test:latest-$arch - platform linux/$arch - output type=docker .; done

## Different methods of building

The CPU can only run binaries for its architecture. x86 CPUs can’t run ARM binaries and vice versa. This is why the buildx came out to emulate software instead of building it natively. When you use cloud-based build platforms such as AWS CodeBuild, the provider generally supports multi-architecture host images and you can build the container image in a native way.

Emulation via Buildx VS Native via AWS CloudBuild

### Buildx via GitHub Action

Using the buildx to emulate multiple platforms and push it to the registry in the CI pipeline.

You should create encrypted dockerhub login credentials(username and password) as a secret for a repository before adding the github action workflow.

In the end, you will see GitHub action is triggered and build the multi-architecture images and push it to the dockerhub automatically.

GitHub Action for building multi-architecture image
DockerHub multi-architecture image

### AWS CodeBuild

With CodePipeline and CodeBuild, we can automate building multi-architecture docker images in a native way and push them to DockerHub. The following diagram shows the architecture.

Automate building multi-architecture images using AWS CodeBuild and CodePipeline

Here is a terraform module that builds multiple architecture docker images using AWS CodeBuild and AWS CodePipeline

you can easily use the custom module to deploy the AWS CodePipline, CodeBuild, SecretManager, and S3 bucket resources via terraform. Here is the configuration.

Before applying the terraform code, please make sure buildspec.yml and buildspec-manifest.yml are placed in your source(github) repo.

Finally, you can see the multiple stages in AWS CodePipeline

AWS CodePipeline for building multi-architecture image
DockerHub multi-architecture image

## Pros and Cons ⭐️

  • GitHub Action: Easy, fast, and supports more architecture such as 386, riscv64, arm/v6, and v7. But rely on the docker buildx feature
  • AWS CodePipeline, CodeBuild: Complex and only supports amd64 and arm64/v8 for now(Docker images provided by CodeBuild). But can implement a variety of CI functions in a native way

## Reference

--

--