Create a multi-arch Docker image for a .NET application

 
 
  • Gérald Barré

We are in a transition period where x64 architectures are not the only architectures available. Apple has switched to ARM with the M1 chip, and Microsoft is also pushing for ARM now. If you want to run your application on ARM64 and x64 architectures, you need to create a Docker image for each architecture. Docker supports multi-arch images, which allow you to create a single image that can run on multiple architectures. In this post, I describe how to create a multi-arch Docker image for a .NET application.

To create a docker image that supports multiple architectures, you need to create multiple images for each architecture and then create a manifest that will reference all the images. The manifest will be used by the Docker client to pull the correct image for the current architecture. So, here's the list of tags you need to create:

  • mysampleapp:1.0.0-x64 which will be the image for x64 architecture
  • mysampleapp:1.0.0-arm64 which will be the image for ARM64 architecture
  • mysampleapp:1.0.0 which will be the manifest that references the previous images

To create the images, you can use the dotnet publish command with a few properties to configure the image. This is easier than creating a Dockerfile and it's faster to build the image.

PowerShell
# Create a new web project
dotnet new web
PowerShell
# Create 2 images for x64 and ARM64
$registry = "ghcr.io"
$image = "meziantou/mysampleapp"
$tag = "latest"

dotnet publish -p:PublishProfile=DefaultContainer --configuration Release --os linux --arch x64 -p:ContainerImageTag=$tag-x64 -p:ContainerRepository=$image -p:ContainerRegistry=$registry
dotnet publish -p:PublishProfile=DefaultContainer --configuration Release --os linux --arch arm64 -p:ContainerImageTag=$tag-arm64 -p:ContainerRepository=$image -p:ContainerRegistry=$registry

Then you can combine the images into a manifest and push the manifest to the registry:

PowerShell
docker manifest create "$registry/${image}:$tag" "$registry/${image}:$tag-x64" "$registry/${image}:$tag-arm64"
docker manifest push "$registry/${image}:$tag"

#Additional resources

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub