Create Multi Architecture Images using Docker with Azure DevOps CICD



This content originally appeared on DEV Community and was authored by Harnoor Puniyani

Introduction

Whenever we create the Docker images, mostly it would be for dev-test purposes or to create a production ready images for the kubernetes. Either of the scenarios, we need the images to built on multi architecture so either they can be deployed on different nodes not limited by the architecture and we can also share our images to the different people.

Prepare Application

In this example I would be using a python based flask application, which just displays a welcome message.

Flask Application Frontend UI

Tools

Ideally this can be achieved using various methods, but the easiest and the fastest thing to do would be to use the docker buildx plugin.

I am using a debian based instance so the steps for installing docker are listed here.

PS: Even after installing, docker buildx version does not work, then try doing docker it would show if there’s any error loading the plugin, for me it was not able to access the plugin files, so I just sudoed as any root user should :p sudo docker buildx version and it worked.

Azure DevOps

Step 0: Create an account on the docker hub, and have the generate the access token, or configure any other registry for that matter.

Step 1: Make sure you have created the service connection to the docker hub.

Azure Devops Service Connection

Step 2: Create a git repo for your application with the Dockerfile, make sure in this app you do not have any credentials or secrets embedded.

Repository Structure

Step 3: Lets create a CICD

Step 4: Use the action docker install Cli, you can give any version or the latest version. To get the list of the docker versions, refer the documentation here

Step 5: Verify if the docker buildx is installed, probably using a script which says version docker buildx version.

Step 6: Now, we can proceed with creating our own builder, as we want our builder to work for multiple architectures/ platform hence we are using a custom builder.

Step 7: Once the builder is created, lets put it to build, remember that the built images remain local to the builder only unless we push it to the registry, alternatively you can also load it into the docker if its not a multi-architecture image

Step 8: That’s it for the building, but as a next step you can use image scanners, to scan them for any vulnerabilities.

CICD YAML

trigger:
  branches:
    include:
      - master

resources:
- repo: self

variables:
  basetag: 'user/imageName'
  buildtag: '$(Build.BuildNumber)'
  latesttag: 'latest'

stages:
- stage: Build
  displayName: Build image
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: ubuntu-latest
    steps:
    - task: DockerInstaller@0
      inputs:
        dockerVersion: '28.3.0'
    - script: docker buildx version
      displayName: Check docker buildx

    - task: Docker@2
      inputs:
        containerRegistry: 'docker-harnoorpuniyani'
        command: 'login'
        addPipelineData: false
        addBaseImageData: false

    - script: |
        docker buildx create --use --name builder
      displayName: create Buildx Builder

    - script: |
        docker buildx build --platform linux/amd64,linux/arm64 -t '$(basetag):$(buildtag)' -t '$(basetag):$(latesttag)' . --push
      displayName: Create and Push Multi Architecture Image

References

Github Repo – harnoor-puniyani/echo-app

Feel free to contribute to this application and Fork it for updates on this repository.

Reach out to me –
linkedin | puniyaniharnoor@gmail.com


This content originally appeared on DEV Community and was authored by Harnoor Puniyani