What OS to target with .NET containers

Given the diversity of operating systems supported by Docker and the differences between .NET Framework and .NET Core, you should target a specific OS and specific versions depending on the framework you are using.

For Windows, you can use Windows Server Core or Windows Nano Server. These Windows versions provide different characteristics (IIS in Windows Server Core versus a self-hosted web server like Kestrel in Nano Server) that might be needed by .NET Framework or .NET Core, respectively.

For Linux, multiple distros are available and supported in official .NET Docker images (like Debian).

In Figure 3-1 you can see the possible OS version depending on the .NET framework used.

Diagram showing what OS to use with which .NET containers.

Figure 3-1. Operating systems to target depending on versions of the .NET framework

When deploying legacy .NET Framework applications you have to target Windows Server Core, compatible with legacy apps and IIS, but it has a larger image. When deploying .NET Core applications, you can target Windows Nano Server, which is cloud optimized, uses Kestrel and is smaller and starts faster. You can also target Linux, supporting Debian, Alpine and others. Also uses Kestrel, is smaller, and starts faster.

You can also create your own Docker image in cases where you want to use a different Linux distro or where you want an image with versions not provided by Microsoft. For example, you might create an image with ASP.NET Core running on the traditional .NET Framework and Windows Server Core, which is a not-so-common scenario for Docker.

Important

When using Windows Server Core images, you might find that some DLLs are missing, when compared to full Windows images. You might be able to solve this problem by creating a custom Server Core image, adding the missing files at image build time, as mentioned in this GitHub comment.

When you add the image name to your Dockerfile file, you can select the operating system and version depending on the tag you use, as in the following examples:

Image Comments
mcr.microsoft.com/dotnet/core/runtime:3.1 .NET Core 3.1 multi-architecture: Supports Linux and Windows Nano Server depending on the Docker host.
mcr.microsoft.com/dotnet/core/aspnet:3.1 ASP.NET Core 3.1 multi-architecture: Supports Linux and Windows Nano Server depending on the Docker host.
The aspnetcore image has a few optimizations for ASP.NET Core.
mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim .NET Core 3.1 runtime-only on Linux Debian distro
mcr.microsoft.com/dotnet/core/aspnet:3.1-nanoserver-1809 .NET Core 3.1 runtime-only on Windows Nano Server (Windows Server version 1809)

Additional resources