Lesson 44 of 45 advanced

Cloud and IIS Deployment

Kestrel runs your app, a proxy sits in front, and settings change per environment

Guess first

Pick an answer. You will see if you were right at the end of the lesson.

What is the role of Kestrel in an ASP.NET Core app?

Open interactive version (quiz + challenge)

Real-world analogy

A restaurant kitchen does not take orders from the street. A host at the door greets guests and passes tickets through the hatch, so the cooks only see tickets. If the host forgets to note that a guest asked for the quiet room, the kitchen assumes the default table. The kitchen is your app, the host is the reverse proxy, and that note is the forwarded headers.

What is it?

Deploying an ASP.NET Core app means publishing it and running it on a host. Often it sits behind a reverse proxy such as nginx or IIS. Kestrel is the cross-platform server inside your app. A proxy handles the public side and passes on headers with the original scheme and client address. On Windows with IIS, you install the Hosting Bundle and run the app through the ASP.NET Core Module. In the cloud you may use App Service or containers. Settings differ per environment, and you read logs to find out why a start fails.

Real-world relevance

A team deploys to IIS for the first time, and the site returns HTTP 500.30, In-Process Startup Failure. The app threw an exception on startup. The Application Event Log and the stdout log, switched on in web.config, show a missing connection string. Out-of-process, the same kind of failure shows as 502.5, Process Failure. Another team puts the API behind nginx, and login redirects start looping. The app still thinks every request is plain http, and adding forwarded headers fixes it. Both problems come from the hosting layer, not from the business code.

Key points

Quick check

Answer from memory — scrolling up first makes it stick less.

Which .NET CLR version does Microsoft recommend for an ASP.NET Core app's IIS application pool?

Behind a reverse proxy, the app sees requests as plain http. Which middleware helps restore the original scheme?

Code example

using System.Net;
using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHealthChecks();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    // Trust only the proxy you know; by default only loopback proxies are trusted
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.5"));
});

var app = builder.Build();

app.UseForwardedHeaders();   // early, before middleware that reads the scheme
app.UseHttpsRedirection();
app.MapHealthChecks("/health");
app.MapGet("/", () => "Shop API is running");
app.Run();

Line-by-line walkthrough

  1. 1. This is a fragment of Program.cs. The using lines bring in IPAddress and the forwarded headers types.
  2. 2. AddHealthChecks registers the health check services.
  3. 3. Configure sets which X-Forwarded headers to read: the client address and the original scheme. KnownProxies lists the one proxy we trust.
  4. 4. UseForwardedHeaders is called early, so middleware after it sees the real scheme and not plain http.
  5. 5. UseHttpsRedirection then works with the restored scheme.
  6. 6. MapHealthChecks exposes a /health endpoint for load balancers and monitors. MapGet adds a simple root route, and Run starts the app.

Spot the bug

var builder = WebApplication.CreateBuilder(args);
builder.Configuration["https_port"] = "443";
var app = builder.Build();

// Runs behind nginx, which terminates TLS and forwards plain http
app.UseHttpsRedirection();
app.MapGet("/", () => "ok");
app.Run();
Need a hint?
What scheme does the app see when nginx forwards the request?
Show answer
nginx terminates TLS and sends plain http, and the app never reads X-Forwarded-Proto. So the app thinks every request is http and redirects to https again. The browser can end up in a redirect loop. Fix: call UseForwardedHeaders with XForwardedProto before UseHttpsRedirection, and trust the proxy.

Explain like I'm 5

A shop has a helper at the door who talks to visitors and then tells the shopkeeper what they want. If the helper forgets to pass on a message, the shopkeeper answers the wrong question. The shopkeeper needs a note from the helper about who really came in.

Fun fact

ASP.NET MVC and Web Forms were built on System.Web, which tied them to IIS on Windows in practice. ASP.NET Core dropped System.Web and brought its own server, Kestrel. So the same app runs on Linux, macOS and in containers.

Hands-on challenge

Say it out loud in 30 seconds: "How do you deploy an ASP.NET Core API to IIS or the cloud?" Then check: did you mention Kestrel behind a reverse proxy, the Hosting Bundle and ASP.NET Core Module for IIS, publishing in Release, configuration and secrets per environment, forwarded headers, and logs for startup failures?

More resources

Open interactive version (quiz + challenge) Download the whole course as PDF / Word

Lock it in

← Back to course: .NET + React Playbook