Docker & .NET: Production-Ready Containerization
Containerizing a .NET API sounds straightforward until your image is 2GB and your startup time is 30 seconds. Let’s do this right.
Multi-Stage Builds
The key to lean .NET images is separating build from runtime:
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /out
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /out .
ENTRYPOINT ["dotnet", "YourApp.dll"]
Environment Configuration
Never bake secrets into images. Use environment variables and map them to appsettings.json keys with double underscore notation: ConnectionStrings__Default.
Health Checks
builder.Services.AddHealthChecks()
.AddDbContextCheck<AppDbContext>();
Then configure Docker to use it: HEALTHCHECK CMD curl -f http://localhost/health || exit 1
Final Thoughts
Good containerization is invisible. Users shouldn’t know or care. Bad containerization makes 3 AM very exciting.