All Blogs Tutorials 5 min read

Docker and Containers for ASP.NET Core Deployments: A Practical Guide

Sandeep Pal
June 3, 2026
Docker and Containers for ASP.NET Core Deployments: A Practical Guide

Why containers changed how .NET teams ship software

If you learned .NET on IIS and click-to-publish, Docker can feel like ceremony for its own sake. Then you deploy the same build to dev, staging, and production and something breaks because a Windows feature pack or GAC assembly differs. Containers do not magically fix architecture, but they give you one artifact that runs the same everywhere Kestrel and your dependencies are bundled correctly. At Toolliyo we teach Docker alongside ASP.NET Core because hiring managers increasingly expect you to explain a Dockerfile in an interview, not just F5 in Visual Studio.

This guide walks through what matters for real ASP.NET Core deployments: image size, secrets, logging, health probes, and when Kubernetes is overkill versus when it saves your team.

What a container is (without the buzzword salad)

A container is an isolated process with its own filesystem slice, network namespace, and resource limits, sharing the host kernel. You build an image from layers; each layer is cached. Your app runs inside that image. For .NET, you typically publish a self-contained or framework-dependent output and copy it into a runtime image based on mcr.microsoft.com/dotnet/aspnet.

Do not confuse containers with virtual machines. A VM boots an entire OS; a container starts your process in milliseconds. That is why horizontal scaling with many small API instances is economical when orchestrated well.

Multi-stage Dockerfile pattern you should memorize

The classic mistake is copying your entire solution into the runtime image with the SDK installed, bloating size and attack surface. Use a build stage, then a slim runtime stage:

# build
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MyApi/MyApi.csproj", "MyApi/"]
RUN dotnet restore "MyApi/MyApi.csproj"
COPY . .
WORKDIR /src/MyApi
RUN dotnet publish -c Release -o /app/publish /p:UseAppHost=false

# runtime
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app
EXPOSE 8080
ENV ASPNETCORE_URLS=http://+:8080
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApi.dll"]

Interview tip: explain why UseAppHost=false helps in Linux containers and why you expose 8080 instead of 80 unless you run as root (you should not).

Configuration and secrets in containerized ASP.NET Core

Twelve-factor style still applies: config via environment variables, secrets via platform secret stores. Never bake connection strings into images. Use ASPNETCORE_ENVIRONMENT, override with Docker Compose or Kubernetes secrets mounted as env vars or files. In Program.cs, the default host builder already reads env vars; know the precedence order: environment variables beat appsettings.json for the same key when configured that way.

  • Development: Docker Compose with a local SQL Server or PostgreSQL container on a user-defined network.
  • Staging/production: Azure Container Apps, App Service for Linux containers, AKS, or AWS ECS—pick one and learn its secret injection model deeply.

Health checks that orchestrators actually use

ASP.NET Core 8+ supports built-in health checks. Map a liveness endpoint separate from readiness if you depend on warm caches or external databases:

builder.Services.AddHealthChecks()
    .AddSqlServer(connectionString, name: "sql");

app.MapHealthChecks("/health/live", new HealthCheckOptions { Predicate = _ => false });
app.MapHealthChecks("/health/ready");

In Kubernetes, liveness restarts a stuck pod; readiness removes it from the service load balancer until dependencies recover. Teams that skip this discover mysterious 502s during database failovers.

Docker Compose for local full-stack workflows

Compose is not production orchestration for everyone, but it is excellent for onboarding. Define your API, database, Redis, and a reverse proxy on one network. Use named volumes for database persistence. Document docker compose up --build in your README so a new hire runs one command.

Common pitfall: API container starts before SQL is ready. Use healthcheck conditions in Compose v2 or a retry policy in your migration entrypoint script.

Logging, observability, and debugging containers

Write logs to stdout and stderr; your platform aggregates them. Add OpenTelemetry for traces and metrics when you move beyond a single VM. When debugging locally, docker logs -f and structured JSON logging beat printf guessing. For production incidents, correlate trace IDs from middleware you add early in the pipeline.

Security checklist for .NET container images

  1. Run as non-root user in the final stage (distroless or chiseled images help).
  2. Scan images in CI with Trivy or similar; fail builds on critical CVEs where possible.
  3. Pin base image tags or digests; avoid floating latest in production pipelines.
  4. Minimize installed packages; smaller surface means fewer patches.

When to add Kubernetes—and when to stop

If you run fewer than five services and one team, managed container hosting plus a good CI/CD pipeline is often enough. Kubernetes pays off with many services, independent scaling, and mature platform teams. Be honest in interviews: "We use App Service containers because ops headcount is two" is a valid engineering decision.

Deployment pipeline sketch

On push to main: restore, test, publish, build image with a semver or git SHA tag, push to registry, deploy to staging with smoke tests hitting /health/ready, promote to production with gradual traffic shift if supported. Roll back by redeploying the previous image tag—another reason immutable artifacts matter.

Practice project for your portfolio

Containerize a small Web API with EF Core migrations run on startup or as a init job, add health checks, wire GitHub Actions to build and push to GitHub Container Registry or Azure ACR, and document environment variables. Mention concrete image size before and after multi-stage builds. That single repo answers more DevOps-flavored interview questions than listing "Docker" on a resume without evidence.

Containers are a packaging and operations tool, not a substitute for clean code. Master the Dockerfile and runtime configuration for ASP.NET Core, and you will deploy faster, debug production with less panic, and speak credibly about how your API actually runs in the cloud.

1 views 0 likes 0 comments
Comments (0)
Sign in to leave a comment
Toolliyo Assistant
Ask about tutorials, ebooks, training, pricing, mentor services, and support. I use public site content only—not admin or internal tools.

care@toolliyo.com

Need callback? Share your details