Back to Blog
Tutorial10 min read2026-06-29

How to Deploy an ASP.NET Core App to the Cloud

Containerize and deploy an ASP.NET Core app: multi-stage publish, Kestrel port binding, health checks, forwarded headers behind a proxy, and a Git-based cloud deploy.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

ASP.NET Core is cross-platform, runs great in Linux containers, and ships with Kestrel — a fast, production-grade web server. The friction points when deploying are almost always the same: binding Kestrel to the right port, handling forwarded headers behind a proxy, and wiring health checks. This guide covers each.

A multi-stage publish

The official .NET images make a clean two-stage build. The SDK image compiles; the smaller ASP.NET runtime image serves.

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app /p:UseAppHost=false

FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app .
ENV ASPNETCORE_URLS=http://0.0.0.0:8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "YourApp.dll"]

The key line is ASPNETCORE_URLS=http://0.0.0.0:8080. By default Kestrel binds to localhost, which is unreachable from outside the container. Many platforms inject PORT; if so, read it:

ASPNETCORE_URLS=http://0.0.0.0:${PORT}

Forwarded headers behind a proxy

In the cloud your app sits behind an ingress or load balancer that terminates TLS. Without forwarded-headers middleware, Request.Scheme reports http and redirects break, and Request.RemoteIpAddress shows the proxy, not the client.

var app = builder.Build();

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

Put this early in the middleware pipeline, before authentication and HTTPS redirection.

Health checks

ASP.NET Core has built-in health checks. Register them and map endpoints:

builder.Services.AddHealthChecks()
    .AddNpgSql(builder.Configuration.GetConnectionString("Default"));

app.MapHealthChecks("/healthz");
app.MapHealthChecks("/readyz", new HealthCheckOptions
{
    Predicate = check => check.Tags.Contains("ready")
});

The AddNpgSql check (from AspNetCore.HealthChecks.Npgsql) verifies database connectivity so readiness reflects real dependencies.

Configuration and connection strings

ASP.NET Core's configuration system reads environment variables with a __ (double underscore) separator for nested keys. To set a connection string:

ConnectionStrings__Default=Host=host;Port=5432;Database=db;Username=u;Password=p

If your platform provides a DATABASE_URL instead, parse it at startup into a Npgsql-style connection string, since the two formats differ.

Don't run as root

The .NET 8 images support a non-root user out of the box:

USER $APP_UID

Combined with the read-only filesystem most platforms encourage, this hardens the container with almost no effort.

Deploying on PandaStack

  1. 1Commit the Dockerfile to your repo.
  2. 2Connect the repo as a container app in the [dashboard](https://dashboard.pandastack.io).
  3. 3PandaStack builds the image with rootless BuildKit in an ephemeral Kubernetes Job — no host Docker socket — and deploys via Helm with automatic SSL.
  4. 4Set ASPNETCORE_URLS and connection-string variables under the app's environment settings.
  5. 5Attach a managed PostgreSQL database and point your connection string at the injected credentials.
  6. 6Configure probes against /healthz and /readyz.

Because PandaStack terminates TLS at Kong ingress, the forwarded-headers middleware above is what makes HTTPS-aware features behave correctly.

Deploy checklist

ConcernFix
Unreachable appBind 0.0.0.0, read PORT
Broken redirects/HTTPSForwarded headers middleware
Health probesMapHealthChecks with DB check
SecurityNon-root $APP_UID
SecretsPlatform env vars, not appsettings

References

  • [ASP.NET Core: Host and deploy in containers](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/docker/)
  • [Configure ASP.NET Core to work with proxy servers](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer)
  • [Health checks in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks)
  • [.NET container images](https://learn.microsoft.com/en-us/dotnet/core/docker/introduction)

Get your ASP.NET Core app online with a managed database and free SSL on PandaStack's free tier — start at [dashboard.pandastack.io](https://dashboard.pandastack.io).

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also