Learn C# - Deployment & Cloud Integration
Series/Learn C#/Episode 19
Episode 19 of 23

Learn C# - Deployment & Cloud Integration

This episode covers deploying .NET applications: Dockerizing with a multi-stage build, deployment to Azure App Service, AWS, GCP, and Kubernetes, runtime configuration for production, and blue-green, canary release, and rollback strategies.

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

Introduction

Code running on a developer's machine guarantees nothing until it runs in production. Good deployment is a process that is documented, repeatable, and recoverable when something goes wrong.

Containers are the answer to the "it works on my machine" problem. A Docker image wraps the application and all its dependencies into one unit that can run anywhere — a laptop, a server, or the cloud.

Episode 19 covers Dockerizing .NET applications, deployment to the cloud and Kubernetes, production configuration, and release strategies that minimize risk.

Dockerizing a .NET Application

An Efficient Multi-stage Build

A .NET image should be built with multiple stages: the first stage compiles, the second contains only the runtime. The result is a small, safe image:

Dockerfile multi-stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY src/Toko.Api/Toko.Api.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 .
ENV ASPNETCORE_ENVIRONMENT=Production
ENTRYPOINT ["dotnet", "Toko.Api.dll"]

The first stage uses the large SDK image to compile, then the runtime stage uses the slim aspnet:8.0 image — containing only the ASP.NET runtime. You already saw dotnet publish in episode 2; now its output is packaged into an image.

Building and Running

Building and running the image
docker build -t toko-api:1.0 .
docker run -p 8080:8080 toko-api:1.0

The docker run -p 8080:8080 toko-api:1.0 command maps the container port to the host port. Production configuration is provided through environment variables when the container is run.

Deployment to the Cloud

Azure App Service, AWS, and GCP

All three major clouds have managed services for ASP.NET Core:

  • Azure App Service: the most native option for .NET, with built-in support for deployment, scaling, and slots.
  • AWS Elastic Beanstalk / ECS: deploy containers to managed AWS services.
  • GCP Cloud Run: runs containers without managing servers, scaling automatically to zero.

The common pattern: CI builds the image and pushes it to a registry (Azure Container Registry, ECR, or Artifact Registry), then the cloud platform pulls and runs it.

Deploying to Kubernetes

In Kubernetes, applications are declared with YAML manifests:

Kubernetes Deployment manifest
apiVersion: apps/v1
kind: Deployment
metadata:
  name: toko-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: toko-api
  template:
    metadata:
      labels:
        app: toko-api
    spec:
      containers:
        - name: toko-api
          image: registry.contoh.id/toko-api:1.0
          ports:
            - containerPort: 8080
          env:
            - name: ASPNETCORE_ENVIRONMENT
              value: Production

Apply it with kubectl:

Applying the manifest
kubectl apply -f deployment.yaml
kubectl rollout status deployment/toko-api

The kubectl rollout status command waits for the deployment to finish. The replicas: 3 value runs three pods — if one dies, the rest keep serving.

Runtime Configuration for Production

Environment Variables as the Source of Truth

In production, don't store secrets in the image. Provide them through environment variables or a secret store:

Running a container with environment
docker run -d -p 8080:8080 \
  -e ASPNETCORE_ENVIRONMENT=Production \
  -e ConnectionStrings__Default="Host=db;Database=toko;Username=app;Password=rahasia" \
  toko-api:1.0

The docker run -e ConnectionStrings__Default=... command overrides the appsettings.json configuration. The double __ format (which you learned in episode 8) maps an environment variable to the configuration hierarchy.

Blue-green, Canary, and Rollback

Release Strategies Without Downtime

  • Blue-green: two environments (blue and green). Release the new version to green, test, then switch traffic over. Rollback is just switching traffic back.
  • Canary: release to a small fraction of users first (for example, 5 percent), watch the metrics, then expand gradually.
  • Rollback: always be ready to restore a previous version. In Kubernetes:
Rollback deployment
kubectl rollout undo deployment/toko-api

The kubectl rollout undo command instantly restores the deployment to a previous revision. With these strategies, a problematic release never becomes a crisis.

Closing

Key takeaways:

  • Docker multi-stage builds produce small, safe images.
  • dotnet publish produces container-ready output.
  • Kubernetes uses YAML manifests and rollout management.
  • Production secrets come from environment variables, not the image.
  • Blue-green, canary, and rollback keep releases safe.

In the next episode 20 we make sure a running application can be monitored: observability and monitoring — logging with Serilog, metrics and tracing with OpenTelemetry, health checks and monitoring endpoints, and incident response and production troubleshooting.

Learn C# - Deployment & Cloud Integration | Learn C#