✓
Home›Tutorials›.NET & ASP.NET Core›ASP.NET Core 10 Deployment Tutorial: Ship Your Containerized API Safely
.NET & ASP.NET Core3 min read

ASP.NET Core 10 Deployment Tutorial: Ship Your Containerized API Safely

Deploy a tested ASP.NET Core 10 container with immutable releases, safe configuration, health checks, rollout validation, and a practical production checklist.

ASP.NET Core 10 Deployment Tutorial: Ship Your Containerized API Safely

A container that starts on a laptop is not yet a deployable service. Deployment connects the tested API to immutable release artifacts, runtime configuration, health checks, rollout behavior, logs, and a rollback path. In this lesson you will take the image from Lesson 7 and define a safe, observable deployment boundary.

Prerequisites

Complete Lesson 7: containerize your tested Minimal API. You need a registry, a Kubernetes-compatible environment or equivalent orchestrator, and separate configuration for development and production. Follow the complete sequence in the .NET and ASP.NET Core learning track.

Working outcome

You will publish one immutable image, deploy it with readiness and liveness endpoints, keep configuration outside the image, verify a rolling release, and know the first evidence to collect if a rollout fails.

Build once and identify the release

Build from a clean checkout after tests pass. Tag the image with an immutable identifier such as the source commit SHA, and record the image digest that is actually deployed. A mutable tag like latest makes it difficult to prove what code handled a request or to roll back reliably. The same image should move through environments; environment differences belong in configuration, not a rebuilt binary.

Expose separate health signals

Readiness answers whether this instance should receive traffic. Liveness answers whether the process is alive enough to keep running. A database dependency can be appropriate for readiness when the API cannot serve without it, but it is usually a poor liveness dependency. Map endpoints deliberately before the first rollout.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHealthChecks()
    .AddCheck("self", () => Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Healthy(), tags: ["live"]);

var app = builder.Build();

app.MapGet("/orders/{id}", (string id) => Results.Ok(new { id }));

app.MapHealthChecks("/health/live", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
{
    Predicate = check => check.Tags.Contains("live")
});
app.MapHealthChecks("/health/ready");

app.Run();
public partial class Program { }

Deploy with explicit runtime inputs

Pass connection strings, signing material, and external-service credentials through the platform’s secret and configuration facilities. Do not bake them into the image, a Dockerfile, source control, or a diagnostic response. Bind the service to the expected port, run as a non-root user, and configure a bounded shutdown window so the process can stop taking traffic before it exits.

Validate a rolling release

  1. Confirm the deployed image digest matches the release record.
  2. Check that new Pods become ready before old ones are removed.
  3. Send a real authenticated request through the production routing path, not only directly to a Pod.
  4. Inspect structured logs and request latency for the new version.
  5. Exercise the rollback procedure in a non-production environment, including a schema-compatible release.

Common mistakes

  • Rebuilding a different image for each environment.
  • Using liveness to test a slow or flaky external dependency.
  • Publishing a database migration that older application versions cannot tolerate during a rolling rollout.
  • Declaring success when a process starts, rather than when it is ready and serving a representative request.
  • Shipping without a version, owner, dashboard, or rollback decision recorded.

Production guidance

Set resource requests from measured behavior, bound request and shutdown time, and preserve correlation IDs across logs and dependencies. Make schema changes additive first, deploy compatible application code, then remove obsolete schema only after old versions are gone. Keep deployment permissions narrow and audit who promoted each release.

Next lesson

Lesson 9 covers observability, performance, and security: instrument request paths, establish useful service-level signals, find bottlenecks, and protect the deployed API without exposing sensitive telemetry.

Sources