There are two supported frameworks for building server-side containerized Docker applications with .NET; .NET Framework and .NET Core. They share many.NET platform components, and you can share code across the two. However, there are fundamental differences between them, and which framework you use will depend on what you want to accomplish. This section provides guidance on when to choose each framework.
General Overview
You should use .NET Core, with Linux or Windows Containers, for your containerized Docker server application when:
- You have cross-platform needs. For example, you want to use both Linux and Windows Containers.
- Your application architecture is based on microservices.
- You need to start containers fast and want a small footprint per container to achieve better density or more containers per hardware unit in order to lower your costs.
In short, when you create new containerized .NET applications, you should consider.NET Core as the default choice. It has many benefits and fits best with the containers philosophy and style of working. An additional benefit of using .NET Core is that you can run side by side .NET versions for applications within the same machine. This benefit is more important for servers or VMs that do not use containers, because containers isolate the versions of .NET that the app needs. (As long as they are compatible with the underlying OS.)
You should use .NET Framework for your containerized Docker server application when:
- Your application currently uses .NET Framework and has strong dependencies on Windows.
- You need to use Windows APIs that are not supported by .NET Core.
- You need to use third-party .NET libraries or NuGet packages that are not available for .NET Core.
Using .NET Framework on Docker can improve your deployment experiences by minimizing deployment issues. This “lift and shift” scenario is important for containerizing legacy applications that were originally developed with the traditional .NET Framework, like ASP.NET WebForms, MVC web apps or WCF (Windows Communication Foundation) services.
When to choose .NET Core for Docker containers
The modularity and lightweight nature of .NET Core makes it perfect for containers. When you deploy and start a container, its image is far smaller with .NET Core than with .NET Framework. In contrast, to use .NET Framework for a container, you must base your image on the Windows Server Core image, which is a lot heavier than the Windows Nano Server or Linux images that you use for .NET Core.
Additionally, .NET Core is cross-platform, so you can deploy server apps with Linux or Windows container images. However, if you are using the traditional .NET Framework, you can only deploy images based on Windows Server Core.
- Developing and deploying cross platform
Clearly, if your goal is to have an application (web app or service) that can run on multiple platforms supported by Docker (Linux and Windows), the right choice is .NET Core, because .NET Framework only supports Windows. .NET Core also supports macOS as a development platform. However, when you deploy containers to a Docker host, that host must (currently) be based on Linux or Windows. For example, in a development environment, you could use a Linux VM running on a Mac.
Visual Studio provides an integrated development environment (IDE) for Windows, and supports Docker development.
Visual Studio for Mac is an IDE, evolution of Xamarin Studio, that runs on macOS and supports Docker-based application development. This should be the preferred choice for developers working in Mac machines who also want to use a powerful IDE.
You can also use Visual Studio Code (VS Code) on macOS, Linux, and Windows. VS Code fully supports .NET Core, including IntelliSense and debugging. Because VS Code is a lightweight editor, you can use it to develop containerized apps on the Mac in conjunction with the Docker CLI and the .NET Core command-line interface (CLI). You can also target .NET Core with most third-party editors like Sublime, Emacs, vi, and the open-source OmniSharp project, which also provides IntelliSense support.
In addition to the IDEs and editors, you can use the .NET Core CLI tools for all supported platform.
2. Using containers for new (“green-field”) projects
Containers are commonly used in conjunction with a microservices architecture, although they can also be used to containerize web apps or services that follow any architectural pattern. You can use .NET Framework on Windows Containers, but the modularity and lightweight nature of .NET Core makes it perfect for containers and microservices architectures. When you create and deploy a container, its image is far smaller with .NET Core than with .NET Framework.
3. Creating and deploying microservices on containers
You could use the traditional .NET Framework for building microservices-based applications (without containers) by using plain processes. That way, because the .NET Framework is already installed and shared across processes, processes are light and fast to start. However, if you are using containers, the image for the traditional .NET Framework is also based on Windows Server Core and that makes it too heavy for a microservices-on-containers approach.
In contrast, .NET Core is the best candidate if you are embracing a microservices-oriented system that is based on containers, because .NET Core is lightweight. In addition, its related container images, either the Linux image or the Windows Nano image, are lean and small making containers light and fast to start.
A microservice is meant to be as small as possible: to be light when spinning up, to have a small footprint, to have a small Bounded Context (check DDD, Domain-Driven Design), to represent a small area of concerns, and to be able to start and stop fast. For those requirements, you will want to use small and fast-to-instantiate container images like the .NET Core container image.
A microservices architecture also allows you to mix technologies across a service boundary. This enables a gradual migration to .NET Core for new microservices that work in conjunction with other microservices or with services developed with Node.js, Python, Java, GoLang, or other technologies.
4. Deploying high density in scalable systems
When your container-based system needs the best possible density, granularity, and performance, .NET Core and ASP.NET Core are your best options. ASP.NET Core is up to ten times faster than ASP.NET in the traditional .NET Framework, and it leads other popular industry technologies for microservices, such as Java servlets, Go, and Node.js.
This is especially relevant for microservices architectures, where you could have hundreds of microservices (containers) running. With ASP.NET Core images (based on the .NET Core runtime) on Linux or Windows Nano, you can run your system with a much lower number of servers or VMs, ultimately saving costs in infrastructure and hosting.
When to choose .NET Framework for Docker containers
While .NET Core offers significant benefits for new applications and application patterns, .NET Framework will continue to be a good choice for many existing scenarios.
- Migrating existing applications directly to a Windows Server container
You might want to use Docker containers just to simplify deployment, even if you are not creating microservices. For example, perhaps you want to improve your DevOps workflow with Docker—containers can give you better isolated test environments and can also eliminate deployment issues caused by missing dependencies when you move to a production environment. In cases like these, even if you are deploying a monolithic application, it makes sense to use Docker and Windows Containers for your current .NET Framework applications.
In most cases for this scenario, you will not need to migrate your existing applications to .NET Core; you can use Docker containers that include the traditional .NET Framework. However, a recommended approach is to use .NET Core as you extend an existing application, such as writing a new service in ASP.NET Core.
2. Using third-party .NET libraries or NuGet packages not available for .NET Core
Third-party libraries are quickly embracing the .NET Standard, which enables code sharing across all .NET flavors, including .NET Core. With the .NET Standard Library 2.0 and beyond the API surface compatibility across different frameworks has become significantly larger and in .NET Core 2.x applications can also directly reference existing .NET Framework libraries (see compat shim).
In addition, the Windows Compatibility Pack was recently released to extend the API surface available for .NET Standard 2.0 on Windows. This pack allows to recompile most existing code to .NET Standard 2.x with little or no modification, to run on Windows.
However, even with that exceptional progression since .NET Standard 2.0 and .NET Core 2.0, there might be cases where certain NuGet packages need Windows to run and might not support .NET Core. If those packages are critical for your application, then you will need to use .NET Framework on Windows Containers.
3. Using .NET technologies not available for .Net Core
Some .NET Framework technologies are not available in the current version of .NET Core (version 2.1 as of this writing). Some of them will be available in later .NET Core releases (.NET Core 2.x), but others do not apply to the new application patterns targeted by .NET Core and might never be available.
The following list shows most of the technologies that are not available in .NET Core 2.x:
- ASP.NET Web Forms. This technology is only available on .NET Framework. Currently there are no plans to bring ASP.NET Web Forms to .NET Core.
- WCF services. Even when a WCF-Client library is available to consume WCF services from .NET Core, as of mid-2017, the WCF server implementation is only available on .NET Framework.
- This scenario might be considered for future releases of .NET Core, there are even some APIs considered for inclusion in the Windows Compatibility Pack.
- Workflow-related services. Windows Workflow Foundation (WF), Workflow Services (WCF + WF in a single service), and WCF Data Services (formerly known as ADO.NET Data Services) are only available on .NET Framework. There are currently no plans to bring them to .NET Core.
4. Using a platform or API that does not support .NET Core
Some Microsoft or third-party platforms do not support .NET Core. For example, some Azure services provide an SDK that is not yet available for consumption on .NET Core. This is temporary, because all Azure services will eventually use .NET Core. For example, the Azure DocumentDB SDK for .NET Core was released as a preview on November 16, 2016, but it is now generally available (GA) as a stable version.
In the meantime, if any platform or service in Azure still doesn’t support .NET Core with its client API, you can use the equivalent REST API from the Azure service or the client SDK on .NET Framework.
Decision Table – .Net Core or .Net Framework
Remember that for Linux containers, you need Linux-based Docker hosts (VMs or servers) and that for Windows Containers you need Windows Server based Docker hosts (VMs or servers).
Architecture / App Type | Linux Container | Windows Container |
Microservices on Containers | .Net Core | .Net Core |
Monolithic App | >nEt Core | .Net Framework .Net Core |
Best-in-class performance and scalability | .Net Core | .Net Core |
Windows Server Legacy app (“brown-field”) migration to containers | – | .Net Framework |
New container based development (“green-field”) | .Net Core | .Net Core |
ASP.NET Core | .Net Core | .Net Framework .Net Core (Recommended) |
ASP.NET 4 (MVC 5, Web API 2, and Web Forms) | – | .Net Framework |
SignalR Services | NET Core 2.1 (when released) or higher version | .NET Framework .NET Core 2.1 (when released) or higher version |
WCF, WF and other legacy frameworks | WCF in .Net Core (only the WCF client library) | .NET Framework WCF in .NET Core (only the WCF client library) |
Consumption of Azure Services | .NET Core (eventually all Azure services will provide client SDKs for .NET Core) | .NET Framework .NET Core (eventually all Azure services will provide client SDKs for .NET Core) |