Multi-Architecture Docker Images

Multi-Architecture Docker Images

I have worked on moving workloads from AMD architecture based EKS nodes to (graviton processors )ARM architecture based EKS nodes . First step in this process is creating multi-arch docker images.

In this article I will answer the following questions

  1. What is a Multi-arch docker Image ?

  2. What is a Docker manifest ?

  3. How to build multi-arch docker images without buildx ?

  4. What is the utility of docker buildx and how it makes it easy to build and push multi-arch docker images ?

What is a Multi-Arch Docker Image ?

A multi-arch (multi-architecture) Docker image is a Docker image that supports multiple CPU architectures, such as x86_64 (AMD64), ARM, ARM64 and others.

The above definition is something you here most of time , but it's not true.

Docker defines it as

A multi-platform image refers to a image that includes variants for multiple different architectures and, in some cases, different operating systems, like Windows.

Though the above definition is true but not entirely because when you are pulling image from a repository that supports multiple architectures - let's say hello-world docker image .

In the command : docker pull hello-world hello-world is not an image in docker registry but a manifest list or index

so, when you are pulling an image that support multi-arch . you are essentially calling an index and docker engine running in the host uses this index to determine the image to pull.

Bear with me for a min if this is confusing. In order to understand all this we need to first understand what are Manifest and Index in context of OCI(Open Container Initiative)

What is Manfiest ?

A Manifest is a Json file that describes the layers, size and digest for a specific architecture .

Unlike the image index, which contains information about a set of images that can span a variety of architectures and operating systems, an image manifest provides a configuration and set of layers for a single container image for a specific architecture and operating system.

What is ImageIndex/Index/Manifest list ?

A manifest list or fat manifest or Index or Image Index is a Json file that references multiple manifests, each for a different architecture. It allows a single image name to be used for different platforms .

Manifest lists or indexes exist for the purpose of combining an array of architecture and platform specific container image manifests under a single reference. This allows a container runtime to select the appropriate index entry that matches the local node's architecture and platform.

This is actually what you refer to or call when you run docker pull command for a multi-arch docker image . so there is no image that support all architectures .

Building a multi-arch docker image with Manifest and Index

Below is the docker image I wrote for petclinic springboot application

ARG IMAGE_TAG=latest
FROM maven:3.9.7-amazoncorretto-17-debian AS build

WORKDIR /app

COPY src ./src

COPY pom.xml . 

RUN mvn package

FROM gcr.io/distroless/java17-debian12:${IMAGE_TAG}

WORKDIR /app

COPY --from=build /app/target/spring-petclinic-3.3.0-SNAPSHOT.jar .

EXPOSE 8080

CMD ["spring-petclinic-3.3.0-SNAPSHOT.jar"]

Building docker images for each platform ( amd and arm )

Since AMD and ARM are most used architectures I will be building images for these architectures. we can build platform specific images in docker using --platform flag

docker build --platform linux/amd64 -t petclinic:3.3.0-SNAPSHOT-amd64 . 

docker build --platform linux/arm64 -t petclinic:3.3.0-SNAPSHOT-arm64 .

when you build a image manifest is automatically created for that image by docker engine describing information about image layers, configuration and digest .

pushing both the images and manifest index to ECR

# Login to AWS ECR 

aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com

# Tag and push the images 

docker tag petclinic:3.3.0-SNAPSHOT-arm64 <account-id>.dkr.ecr.us-east-1.amazonaws.com/petclinic:3.3.0-SNAPSHOT-arm64

docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/petclinic:3.3.0-SNAPSHOT-arm64

 docker tag petclinic:3.3.0-SNAPSHOT-amd64 <account-id>.dkr.ecr.us-east-1.amazonaws.com/petclinic:3.3.0-SNAPSHOT-amd64

docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/petclinic:3.3.0-SNAPSHOT-amd64

Now In order to create a "multi-arch docker image" we need to create a manifest list or fat manifest or index refering both the images .

# Create manifest using below command 

docker manifest create <account-id>.dkr.ecr.us-east-1.amazonaws.com/petclinic:3.3.0-SNAPSHOT  <account-id>.dkr.ecr.us-east-1.amazonaws.com/petclinic:3.3.0-SNAPSHOT-amd64 <account-id>.dkr.ecr.us-east-1.amazonaws.com/petclinic:3.3.0-SNAPSHOT-arm64


# Push the manifest to ECR 

docker manifest push <account-id>.dkr.ecr.us-east-1.amazonaws.com/petclinic:3.3.0-SNAPSHOT

The information about manifest list or index can be retrieved using command

docker manifest inspect <account-id>.dkr.ecr.us-east-1.amazonaws.com/petclinic:3.3.0-SNAPSHOT

Minimize image

Edit image

Delete image

In order to make the above process easy and faster using docker we have a docker tool kit called docker buildx .

What is Docker Buildx ?

Docker Buildx is an extended build tool for docker that provides advanced build capabilities beyond traditional docker build command . It is part of Docker CLI and leverages the BuildKit backend to enhance docker build process. Here are some of the key features and benefits of Docker Buildx :

Key Features of Docker Buildx

  1. Multi-Platform Builds: Build images for multiple architectures (e.g., amd64, arm64) simultaneously. This is especially useful for creating multi-architecture images that can run on different types of hardware.

  2. Cache Management: Improved caching mechanisms for faster builds. It allows for exporting and importing build caches to speed up the build process.

  3. Advanced Build Options: Support for features such as build secrets, SSH forwarding, and inline cache, which provide more control and flexibility in the build process.

  4. Custom Build Contexts: Allows specifying custom build contexts from various sources, including local directories, Git repositories, and external URLs.

  5. Parallel Builds: Buildx can execute multiple build steps in parallel, significantly speeding up the build process.

Since Docker is the most popular container engine .Docker buildx can be used to ease build and publish of multi-arch docker images.

Enabling Docker Buildx

Buildx is included with Docker Desktop and Docker Engine, but you may need to create and switch to a new builder instance to use it:

Create a New Builder Instance:

docker buildx create --name mybuilder --use

This command creates a new builder instance named mybuilder and sets it as the default builder.

Build & Push Multi-Platform Images

One of the most powerful features of Docker Buildx is the ability to build multi-platform images. Here’s how you can build an image for both amd64 and arm64 platforms:

#Login to aws ECR Container registry using appropriate command 

aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com

# use below command to build and push to ECR 

docker buildx build --platform linux/amd64,linux/arm64 -t <account-id>.dkr.ecr.us-east-1.amazonaws.com/petclinic:3.3.0-SNAPSHOT-buildx --push .

In this command:

  • --platform linux/amd64,linux/arm64: Specifies the target platforms.

  • -t myapp:latest: Tags the built image.

  • --push: Pushes the image to the specified registry after building. [ optional ]

When executed docker using buildx builds images for both the architectures in parallel , thereby reducing the build time and reduces steps required to create manifest and push to container registry .

The below images shows all the images and image index pushed to ECR by docker and docker buildx

Minimize image

Edit image

Delete image

In the above picture the untagged images present are the ones pushed by the docker buildx.

To validate if images are pulled according to the architecture I deleted the images in system and pulled the image from ECR .

Minimize image

Edit image

Delete image

On running docker inspect command , I found the architecture to be arm64 which is same as that of my system.

Minimize image

Edit image

Delete image

Conclusion :

This article deep dives into what multi-arch docker images really are . It discusses about underlying concepts like manifest, index what they are and how they differ from each other , that make multi-arch docker image happen. This article shows two different approaches to build these multi-arch docker images using just docker and docker buildx .