.NET SDK Container Build with Azure DevOps
Streamline Your Container Builds: .NET SDK Container Build with Azure DevOps
Building container images for your .NET applications has evolved significantly. While Dockerfiles have been the go-to for years, the .NET SDK Container build (PublishProfile=DefaultContainer, Containerize) offers a compelling alternative, especially when integrated into your Azure DevOps build pipelines. This approach brings a host of benefits, from simplifying your build infrastructure to accelerating your deployment process.
Why Choose .NET SDK Container Build at all?
- No Dockerfile Needed: Not needing to maintain custom Dockerfiles for each application being the most obvious advantage (which can quickly become non trivial with cache mounts and copying files) … the .NET SDK Container build builds the container images using a non root user by default. It also implicitly has the advantage of a multi-stage Dockerfile build … so it out of the box comes with a solid setup security wise.
- Improved build times: Typically you will enjoy much faster build times.
- Default Image Tags: The .NET SDK Container build by default adds useful tags (LABEL in Dockerfile) to the image. Additional Tags and properties can be configured from the project file.
Why Choose .NET SDK Container Build in your DevOps pipeline?
- No Docker/Podman Installation Needed: No need to install Docker or Podman (or tools like BuildKit or Buildah) on your build agents. This is particularly beneficial for self-hosted agents, where setting up rootless mode and managing permissions can be … not so obvious.
- Flexible Build Agent OS: You might not even need a Linux-based build agent. A Windows build agent, without any additional container tools, can perfectly build Linux-based container images. The only exception is when performing Ahead-of-Time (AOT) compilation; in that case, the build environment’s OS must match the runtime OS of your container image.
- Direct to Remote Registry: No local registry required. The SDK Container build can publish directly to your remote container registry, streamlining your deployment workflow. If you need to perform additional operations on the image before pushing, you can also generate it as a
tar.gz
file. - Simplified Authentication: Passing username/password or authentication tokens to your remote registry is as simple as setting two environment variables (
SDK_CONTAINER_REGISTRY_UNAME
,SDK_CONTAINER_REGISTRY_PWORD
), which you can initialize using pipeline variables. Though the container build can use docker login credentials (docker login
or the cred file), this is not required.
Bonus: if you have ever run docker builder prune
and seen how many GiB disk space this consumes … (to be fair, .NET SDK container build caches a lot of stuff below $temp/Containers).
Integrating into Your Azure DevOps Pipeline
Here’s how to set up your Azure DevOps pipeline to leverage the .NET SDK Container build:
Restore .NET SDK
First, ensure you’re using a compatible .NET SDK version. While versions 8 and higher support this capability, newer versions often come with more features (like multi-architecture images) and fewer bugs. You can safely build applications targeting the .NET 8 runtime using a .NET 9 or even .NET 10 SDK; newer is generally better for the SDK itself.
- task: UseDotNet@2
displayName: 'Use .NET SDK'
inputs:
packageType: 'sdk'
useGlobalJson: false
version: '8.x' # Use the latest stable version or a specific one (e.g., '9.x')
Publish with PublishProfile=DefaultContainer
The magic happens in the publish
command. By specifying PublishProfile=DefaultContainer
, you instruct the .NET SDK to build your application into a container image. You can also pass environment variables for registry authentication and proxy settings.
- task: DotNetCoreCLI@2
displayName: dotnet publish
inputs:
command: publish
projects: '$/*.csproj'
arguments: '-r linux-x64 -p:PublishProfile=DefaultContainer --configuration $(BuildConfiguration)'
zipAfterPublish: false
env:
SDK_CONTAINER_REGISTRY_UNAME: $(ContainerRegistryUserName) # Your container registry username
SDK_CONTAINER_REGISTRY_PWORD: $(ContainerRegistryPassword) # Your container registry password/token
HTTP_PROXY: "http://yourproxy.com:8080" # Optional: if you are behind a proxy
Conclusion
The .NET SDK Container build dramatically simplifies your containerization workflow within Azure DevOps. By reducing infrastructure requirements, accelerating build times, and offering flexible publishing options, it empowers developers to build and deploy containerized .NET applications with greater ease and efficiency. Embrace this powerful feature to streamline your CI/CD pipelines and focus on what matters most: delivering great software.