Docker and C#: A Complete Guide to Containerizing .NET Applications
Containerization has become the de facto standard for deploying modern applications. If you develop in C# (.NET), Docker allows you to package your application along with all its dependencies into a lightweight, isolated container. In this article, we will walk through the process from creating a simple Dockerfile to publishing and running a ready image. You will learn how to containerize a C# application, optimize image size, and use best practices.
1. Docker Basics for .NET Developers
Docker is a platform for developing, shipping, and running applications in containers. A container is a standardized unit of software that includes code and all its dependencies. Unlike virtual machines, containers share the host operating system's kernel, making them faster and lighter.
For C# (.NET), Docker is especially useful because it solves the "it works on my machine" problem — you ensure the application behaves the same on a developer's machine, test server, and in production. Key components:
- Docker Engine — the container runtime environment
- Dockerfile — a text file with instructions for building an image
- Image — an immutable template for creating containers
- Container — a running instance of an image
Install Docker Desktop for Windows/Mac or Docker Engine for Linux. After installation, verify it works with the command:
docker --version2. Creating a Dockerfile for a C# (.NET) Application
Let's start with a simple ASP.NET Core Web API application. Create a new project:
dotnet new webapi -n MyDockerAppcd MyDockerAppNow create a Dockerfile (no extension) in the project root. Here is a basic version with a multi-stage build:
# Stage 1: Build the applicationFROM mcr.microsoft.com/dotnet/sdk:8.0 AS buildWORKDIR /src
# Copy the csproj and restore dependenciesCOPY ["MyDockerApp.csproj", "."]RUN dotnet restore
# Copy the rest of the code and build the projectCOPY . .RUN dotnet publish -c Release -o /app/publish
# Stage 2: Create a minimal runtime imageFROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtimeWORKDIR /appEXPOSE 80EXPOSE 443
# Copy the published application from the first stageCOPY --from=build /app/publish .
# Entry pointENTRYPOINT ["dotnet", "MyDockerApp.dll"]Explanation of key instructions:
FROM— specifies the base image (SDK for building, ASP.NET for running)WORKDIR— sets the working directoryCOPY— copies files from the build context into the imageRUN dotnet restore— restores NuGet packagesRUN dotnet publish— compiles and publishes the applicationEXPOSE— indicates the ports the container will listen onENTRYPOINT— the command executed when the container starts
Multi-stage builds are critical for C#: the final image contains only the runtime and your application, without the SDK and source code. This reduces the image size from ~1.5 GB to ~200 MB.
3. Building and Running the Container
Build the Docker image:
docker build -t my-dotnet-app:latest .The -t flag sets the tag (name:version). The dot at the end means the current directory is the build context.
Run the container:
docker run -d -p 8080:80 --name my-app my-dotnet-app:latestParameters:
-d— run in detached mode (background)-p 8080:80— port mapping: host port 8080