Create a multi-arch Docker image for a .NET application
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 architecturemysampleapp:1.0.0-arm64
which will be the image for ARM64 architecturemysampleapp: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.
# Create a new web project
dotnet new web
# 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:
docker manifest create "$registry/${image}:$tag" "$registry/${image}:$tag-x64" "$registry/${image}:$tag-arm64"
docker manifest push "$registry/${image}:$tag"
#Additional resources
- Announcing built-in container support for the .NET SDK
- .NET SDK Container Building Tools
- docker manifest create
- docker manifest push
Do you have a question or a suggestion about this post? Contact me!