Learn .NET - Deployment & Cloud Native
Series/Learn .NET/Episode 19
Episode 19 of 23

Learn .NET - Deployment & Cloud Native

This episode brings your application to production: Dockerizing .NET applications with multi-stage builds, deployment to Kubernetes, Azure, AWS, and GCP, managing configuration and secrets at runtime, and blue-green, canary release, and rollback strategies.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Code that passes tests is not yet production-ready. Episode 19 covers deployment and cloud native: wrapping .NET applications in containers, deploying to Kubernetes and cloud providers, managing configuration and secrets at runtime, and releasing new versions without downtime.

After this episode, you will have an application that does not just run on your machine, but lives in production infrastructure — with safe release strategies and the ability to roll back when something goes wrong.

Dockerizing .NET Applications

Multi-Stage Builds

An efficient .NET image is built in two stages: one for compilation, one for runtime. The Dockerfile:

Multi-stage Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /app/publish
 
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "Catalog.Api.dll"]

The build stage uses the SDK image to compile; the runtime stage only copies artifacts into the lightweight aspnet image. The result is a small image because it does not carry the SDK. This framework-dependent image needs the ASP.NET base image, which already contains the runtime.

Build and Run

Build and run the image:

Build and run the image
docker build -t catalog-api:1.0.0 .
docker run -p 8080:80 catalog-api:1.0.0

docker run -p 8080:80 maps host port 8080 to container port 80, where Kestrel listens. For non-root containers, use USER app in the Dockerfile — the .NET base image provides a secure app user by default.

Deployment to Kubernetes, Azure, AWS, and GCP

Kubernetes Deployment

Kubernetes manages containers with deployments, services, and scaling. An example manifest:

Deployment manifest
apiVersion: apps/v1
kind: Deployment
metadata:
  name: catalog-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: catalog-api
  template:
    metadata:
      labels:
        app: catalog-api
    spec:
      containers:
        - name: catalog-api
          image: registry.example.com/catalog-api:1.0.0
          ports:
            - containerPort: 80
          readinessProbe:
            httpGet:
              path: /api/health
              port: 80

This deployment runs 3 replicas and checks health via a probe on /api/health — the endpoint we built in episode 11. Health probes matter: unhealthy Pods do not receive traffic.

Cloud Providers

  • Azure: AKS for Kubernetes, or App Service for managed hosting.
  • AWS: ECS or EKS; dotnet runs natively on Linux.
  • GCP: GKE or Cloud Run.

Choose managed Kubernetes for full control, or a managed platform to reduce operations. .NET applications run identically on all three because of containers.

App Configuration, Secrets, and Runtime Environment

Injecting Configuration at Runtime

Configuration is injected through environment variables (episode 10). In Kubernetes, use ConfigMaps and Secrets:

Kubernetes Secret
apiVersion: v1
kind: Secret
metadata:
  name: catalog-secrets
stringData:
  ConnectionStrings__Default: "Server=db;Database=Catalog"

The ConnectionStrings__Default key maps directly to ConnectionStrings:Default in the application — no code changes needed. Secrets in Kubernetes are stored encrypted; for full production, consider integrating with a vault or a cloud provider.

The 12-Factor Approach

Cloud-native applications follow 12-factor principles: configuration from the environment, statelessness, and restart readiness. .NET applications with the Generic Host and DI already support most of these principles naturally.

Blue-Green, Canary, and Rollback

Blue-Green Deployment

Blue-green runs two environments at once: the new version (green) is fully prepared, then traffic is switched after the health check passes. Rollback is moving traffic back to blue — instant and without downtime.

Canary Releases

Canary sends a small portion of traffic to the new version while monitoring errors:

Enable canary in Kubernetes
kubectl set image deployment/catalog-api \
  catalog-api=registry.example.com/catalog-api:1.1.0
kubectl rollout status deployment/catalog-api

kubectl rollout status monitors the gradual rollout. If the error rate rises, kubectl rollout undo returns to the previous version — automated rollback becomes a trusted emergency strategy. Canary is finer-grained than blue-green because the risk exposure is smaller.

Warning

Prepare the rollback from the start of a release: tag image versions clearly, keep the previous manifests, and make sure the database schema is compatible forward and backward.

Deployment Practice Summary

  • Build images with multi-stage and a lightweight runtime base image.
  • Include health probes in Kubernetes manifests.
  • Inject configuration and secrets through the environment.
  • Choose managed Kubernetes or a managed platform per team needs.
  • Combine blue-green, canary, and rollback for safe releases.

Closing

Key takeaways:

  • Multi-stage Docker produces small, secure images.
  • Kubernetes deployments are managed with manifests and health probes.
  • Azure, AWS, and GCP support .NET natively via containers.
  • Configuration and secrets are injected through environment variables.
  • Blue-green switches traffic between full environments.
  • Canary routes a fraction of traffic and supports fast rollback.

In the next episode 20 we will discuss observability and production support — logging with Serilog, metrics, tracing, and OpenTelemetry integration, health checks and monitoring endpoints, and incident management, diagnostics, and production support readiness.

Learn .NET - Deployment & Cloud Native | Learn .NET