Build multi-arch container images

Build multi-arch container images
  • Current days raise of ARM based architecture in Apple machines and Cloud Compute Virtual machines, now we are in timeline to build our container images to support multiple architecture.
How to build container images to support multiple architecture?
Solution: Let use Docker CLI and buildx.

Docker CLI and buildx ships default on Docker Desktop 19.03 or later.

buildx is in experiment state, which x denotes experiment. expecting stable version soon.

Demo

  1. Let create simple Go application
  2. Create Dockerfile
  3. Docker login
  4. Create builder
  5. Verify builder
  6. Create repo in Dockerhub
  7. Build and Push for multi arch docker images to Docker hub.
  8. Verify multi arch images on Docker hub console
  9. Verify multi arch images using imagetools
  10. Create Amazon Linux EC2 machine with AMD arch and install docker engine
  11. Check the machine architecture
  12. Pull and Run docker image on EC2 AMD machine
  13. Verify image on EC2 AMD machine
  14. Create Amazon Linux EC2 machine with ARM arch and install docker engine
  15. Check the machine architecture
  16. Pull and Run docker image on EC2 ARM machine
  17. Verify image on EC2 ARM machine

Let create simple Go application

Create file main.go

package main			

import (
	"fmt"
	"net/http"
	"runtime"
)

func main() {
	// Define a handler function for the root ("/") route
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// Get the operating system architecture
		arch := runtime.GOARCH

		// Display a message with the operating system architecture
		message := fmt.Sprintf("Hello, Golang Web! Running on %s architecture.", arch)
		fmt.Fprintln(w, message)
	})

	// Specify the port to listen on
	port := 8080
	addr := fmt.Sprintf(":%d", port)

	// Start the HTTP server
	fmt.Printf("Server listening on http://localhost:%d\n", port)
	http.ListenAndServe(addr, nil)
}
above go program display running Arch

Create Dockerfile

# Use the official Golang base image
FROM golang:latest

# Set the working directory inside the container
WORKDIR /app

# Copy the local code into the container
COPY . .

# Build the Go application
RUN go build -o dockermultiarch ./main.go

# Expose the port the app runs on
EXPOSE 8080

# Command to run the executable
CMD ["./dockermultiarch"]

Docker login

Login to dockerhub , create account if not already https://hub.docker.com

$ docker login

On Settings ➡️Features in development ➡️

Ensure Ticked ✅ Use containerd for pulling and storing images

Create builder

$ docker buildx create --name kubelancerbuilder --bootstrap --use

Verify builder

$ docker buildx inspect kubelancerbuilder

Create repo in Dockerhub

Build and Push for multi arch docker images to Docker hub

docker buildx build --push --platform linux/arm64,linux/amd64  --tag hariharankube/dockermultiarch:v1.0.0 .

Verify multi arch images on Docker hub console

Verify multi arch images using imagetools

docker buildx imagetools inspect hariharankube/dockermultiarch:v1.0.0 

Create Amazon Linux EC2 machine with AMD arch and install docker engine

aws ec2 run-instances --image-id ami-07caf09b362be10b8 --instance-type t2.micro --key-name harikey --security-group-ids sg-07f79b5004ede58e4 --subnet-id subnet-046f481b26c67895a
ssh -i "harikey.pem" ec2-user@ec2-3-81-0-208.compute-1.amazonaws.com

Check the Machine Architecture

arch
sudo yum install docker 
sudo systemctl status docker.service

Pull and Run docker image on EC2 AMD machine

docker pull hariharankube/dockermultiarch:v1.0.0
upload in progress, 0
docker inspect hariharankube/dockermultiarch:v1.0.0 | grep -i Architecture

Verify image on EC2 AMD machine

docker image ls 

Create Amazon Linux EC2 machine with ARM arch and install docker engine

aws ec2 run-instances --image-id ami-0092a7ee6b8b2222a --instance-type t4g.nano --key-name harikey --security-group-ids sg-07f79b5004ede58e4 --subnet-id subnet-00d73a97de4c0f03d
ssh -i "harikey.pem" ec2-user@ec2-3-83-20-17.compute-1.amazonaws.com

Check the Machine Architecture

arch
sudo yum install docker 
sudo systemctl status docker.service 

Pull and Run docker image on EC2 ARM machine

docker pull hariharankube/dockermultiarch:v1.0.0
docker inspect hariharankube/dockermultiarch:v1.0.0 | grep -i Architecture

Verify image on EC2 ARM machine

docker image ls 
Happy Computing 😄