.NET Academy

Running in production

Environments, containers, CI/CD, health checks and observability — keeping a backend alive.

12 min read

You will learn

  • Explain why apps move through separate environments
  • Describe what containers solve
  • Outline a CI/CD pipeline
  • Use logs, metrics, traces and health checks to understand a live system

Shipping is the beginning

Writing the code is half the job. The other half is getting it to production safely, often, and keeping it healthy there. This is the world of DevOps: developers and operations sharing responsibility for running software. Track 13 shows the .NET tooling; here are the concepts.

Environments

Changes travel through separate environments before reaching users:

EnvironmentPurpose
DevelopmentYour machine; fast feedback, fake or local services
Test / CIAutomated tests on every change
StagingA production-like copy for final checks and demos
ProductionReal users, real data

Each environment has its own configuration (connection strings, feature flags, log levels) and its own secrets — production data never belongs on a laptop.

Containers

A container packages your app with everything it needs — the .NET runtime, native libraries, configuration — into an image that runs identically on any machine with a container runtime.

FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY ./publish .
ENTRYPOINT ["dotnet", "Shop.Api.dll"]
  • Images are built once and promoted unchanged from test to production.
  • Containers start in seconds and are disposable — a perfect match for stateless servers.
  • Orchestrators like Kubernetes, Azure Container Apps or AWS ECS run many containers, restart failed ones, scale them and roll out new versions.

CI/CD

Continuous Integration (CI): every push triggers an automated pipeline — restore, build, run tests, run analyzers. A broken build is noticed in minutes, not weeks.

Continuous Delivery/Deployment (CD): every passing change is packaged (e.g. as a container image) and deployed to staging, then production — automatically or with one click.

push ──▶ build ──▶ unit tests ──▶ integration tests ──▶ build image ──▶ deploy staging ──▶ smoke tests ──▶ deploy prod

Safe rollout strategies: rolling (replace instances gradually), blue/green (switch traffic between two full environments), canary (send 5% of traffic to the new version first), and feature flags (deploy code turned off, enable it later).

Observability

When something breaks at 3 a.m., you need to understand a system you can't attach a debugger to. The three pillars:

SignalAnswersExample
LogsWhat happened in this specific event?Payment for order 42 declined: insufficient funds
MetricsHow is the system behaving over time?Requests/s, error rate, p95 latency, CPU, queue length
TracesWhere did this request spend its time, across services?API 20 ms → orders service 35 ms → database 210 ms

OpenTelemetry is the vendor-neutral standard for all three; .NET has it built in, and you can send the data to Grafana, Jaeger, Azure Monitor, Datadog and others.

Watch the four golden signals: latency, traffic, errors, saturation. Alert on symptoms users feel (error rate, latency), not on every CPU spike.

Health checks

Load balancers and orchestrators need to know whether an instance is OK:

  • Liveness — is the process alive? If not, restart it.
  • Readiness — can it serve traffic right now (database reachable, warm-up done)? If not, stop sending requests to it.
builder.Services.AddHealthChecks()
    .AddDbContextCheck<ShopDb>();     // from a health-checks package
 
app.MapHealthChecks("/health");

You build it, you run it

Teams that operate their own services write more observable, more robust code — because they're the ones paged when it fails.

Key takeaways

  • Code moves through development, test, staging and production, each with its own config and secrets.
  • Containers package app + runtime into images that run the same everywhere; orchestrators run them at scale.
  • CI tests every change automatically; CD deploys passing changes safely (rolling, blue/green, canary).
  • Observe production with logs, metrics and traces (OpenTelemetry), and expose liveness/readiness health checks.

Quiz

4 questions · 3 correct to pass
  1. 1.What problem do containers (e.g. Docker) mainly solve?

  2. 2.What's the difference between continuous integration and continuous delivery?

  3. 3.Which signal best answers "how many requests per second are failing right now"?

  4. 4.What's the difference between a liveness and a readiness health check?

To complete this lesson

  • ○ Pass the quiz (3/4 correct)