Containerizing an ASP.NET Core App
A production Dockerfile for ASP.NET Core typically uses a multi-stage build: an SDK image (mcr.microsoft.com/dotnet/sdk:8.0) compiles and publishes the app in a build stage, then the output is copied into a much smaller runtime-only image (mcr.microsoft.com/dotnet/aspnet:8.0) for the final stage. This keeps the shipped image lean — often under 200MB — because it excludes the full SDK, compilers, and NuGet caches that were only needed during the build.
Cricket analogy: A multi-stage Docker build is like a cricket academy where young players train with the full coaching staff, video analysis rig, and equipment shed (the SDK stage), but only the polished player and their kit bag (the runtime image) actually travel to the match, leaving the training infrastructure behind.
Publishing to Azure App Service
Azure App Service for Containers can pull an image directly from Azure Container Registry (ACR) and run it on managed infrastructure, handling TLS termination, autoscaling, and deployment slots for you. A typical CI/CD pipeline in GitHub Actions builds the image, pushes it to ACR with az acr build, then triggers a slot swap or a webhook that tells App Service to pull the new tag, giving you near-zero-downtime deploys.
Cricket analogy: Azure App Service pulling images from a container registry is like the BCCI pulling a certified, vetted player roster from a central registry for a tour, rather than each state team independently assembling players ad hoc — it's a controlled, repeatable source of truth.
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["OrdersApi/OrdersApi.csproj", "OrdersApi/"]
RUN dotnet restore "OrdersApi/OrdersApi.csproj"
COPY . .
WORKDIR /src/OrdersApi
RUN dotnet publish -c Release -o /app/publish --no-restore
# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app
EXPOSE 8080
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "OrdersApi.dll"]Configuration and Secrets in Azure
Instead of baking connection strings into appsettings.json, production configuration should come from Azure App Configuration or Azure Key Vault, referenced via App Service's Key Vault references (@Microsoft.KeyVault(SecretUri=...)) in Application Settings, or loaded at startup with AddAzureKeyVault(). This keeps secrets out of source control and lets you rotate a database password without redeploying the container.
Cricket analogy: Keeping secrets in Azure Key Vault instead of appsettings.json is like a team keeping its actual match strategy in a locked dressing room rather than printing it in the publicly distributed matchday program — the plan stays confidential and can change without reprinting anything.
Never commit a connection string or API key to appsettings.json in source control, even temporarily 'for testing' — git history retains it forever unless you rewrite history, and secrets scanners on public repos will flag it within minutes. Use user secrets locally and Key Vault in production.
Deployment Slots and Rollbacks
Deployment slots let you deploy a new container to a staging slot with its own hostname, run smoke tests against it, then swap it into production with near-zero downtime because App Service warms up the new slot before rerouting traffic. If the new version misbehaves, swapping back to the previous slot is a fast rollback that doesn't require rebuilding or redeploying anything.
Cricket analogy: Deployment slots are like a team playing a full warm-up match on a practice ground identical to the real stadium before the actual fixture, and if something goes wrong they simply revert to their previous, proven starting eleven rather than the untested lineup.
App Service deployment slots also let you test configuration changes safely — 'slot settings' can be marked sticky so they stay with a slot rather than following the swap, which is useful for values like a slot-specific feature flag that should remain in staging even after production swaps in the new code.
- Use multi-stage Dockerfiles to keep the runtime image lean
- Azure App Service for Containers pulls images from ACR and manages scaling/TLS
- Store secrets in Key Vault or App Configuration, never in appsettings.json
- Key Vault references let you rotate secrets without redeploying
- Deployment slots warm up new versions before a near-zero-downtime swap
- Rollback is as simple as swapping back to the previous slot
- CI/CD pipelines typically build, push, and trigger slot swaps automatically
Practice what you learned
1. Why use a multi-stage Dockerfile for an ASP.NET Core app?
2. Where should production connection strings and secrets be stored, per best practice?
3. What is the purpose of a deployment slot in Azure App Service?
4. What does 'az acr build' typically do in a CI/CD pipeline?
Was this page helpful?
You May Also Like
Logging and Observability with Serilog
Configure structured logging with Serilog and pair it with metrics and distributed tracing to build real observability into an ASP.NET Core API.
Integration Testing with WebApplicationFactory
Use Microsoft.AspNetCore.Mvc.Testing's WebApplicationFactory to spin up an in-memory ASP.NET Core app and test real HTTP requests through the full middleware pipeline.
ASP.NET Core Interview Questions
A focused review of the ASP.NET Core fundamentals, common pitfalls, and system-design questions that come up most often in technical interviews.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics