.NET is cross-platform and container-native now
If your mental model of .NET hosting is still "IIS on Windows," update it. Modern .NET (8/9 and beyond) runs first-class on Linux, builds tiny container images, supports native AOT for fast-starting trimmed binaries, and is genuinely excellent for high-throughput web services. This widens your hosting options enormously.
The runtime model to understand: ASP.NET Core apps run on Kestrel, a fast built-in web server. In production Kestrel typically sits behind a reverse proxy (the platform's ingress/load balancer) which terminates TLS and forwards traffic. You don't need IIS or Nginx yourself on most modern platforms — the platform's proxy handles it.
Build targets
| Target | Startup | Size | Notes |
|---|---|---|---|
| Framework-dependent | Normal | Small (no runtime) | Host must have .NET runtime |
| Self-contained | Normal | Larger | Bundles the runtime |
| Native AOT | Very fast | Small, trimmed | Limited reflection; great for scale-to-zero |
Native AOT is the headline feature for cold-start-sensitive hosting — it compiles ahead of time to a native binary with fast startup and low memory. The catch is the usual AOT trade-off: reflection and some dynamic features need care, and not every library is AOT-friendly yet.
The container build
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app
FROM mcr.microsoft.com/dotnet/aspnet:9.0
WORKDIR /app
COPY --from=build /app .
ENV ASPNETCORE_URLS=http://+:8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "YourApp.dll"]Set ASPNETCORE_URLS so Kestrel binds the port the platform expects, and make sure you call app.UseForwardedHeaders() so the app sees the real client scheme/IP behind the proxy.
The platforms
Azure App Service / Container Apps
The natural home for .NET. Deep tooling, managed SQL, identity integration, and the smoothest deploy story for Microsoft-stack teams. If you're already in Azure or use SQL Server heavily, this is the path of least resistance.
AWS and Google Cloud
App Runner, ECS/Fargate (AWS), and Cloud Run (GCP) all run .NET Linux containers well. Cloud Run + native AOT is a particularly nice scale-to-zero combination.
Railway and Render
Both deploy .NET containers on git push with managed Postgres alongside. Simpler than the hyperscalers, good for small/medium services. Note: managed SQL Server is rarer on these — many use Postgres with EF Core instead.
PandaStack
My platform, in fairness. PandaStack runs ASP.NET Core as a container app. Provide the Dockerfile above, connect the repo, and the build runs with rootless BuildKit in an ephemeral K8s Job, then deploys via Helm. Attach managed PostgreSQL, MySQL, MongoDB, or Redis and the connection string is injected — wire it into EF Core via configuration. Native AOT pairs well with PandaStack's scale-to-zero free tier. You also get cronjobs, live logs, custom domains, and automatic SSL.
Honest limits: PandaStack does not offer managed SQL Server — if your app is tied to SQL Server specifically, Azure is the better fit; with EF Core you can target managed Postgres/MySQL instead. It's a newer platform, and free-tier apps cold-start on preemptible nodes (much less painful with native AOT).
EF Core and migrations
Run migrations as a deliberate deploy step, not blindly on startup across replicas:
dotnet ef database update --connection "$DATABASE_URL"Or generate an idempotent SQL script in CI and apply it once. For provider choice, Npgsql.EntityFrameworkCore.PostgreSQL is a mature, popular path when you're not on SQL Server.
Production checklist
ASPNETCORE_ENVIRONMENT=ProductionandASPNETCORE_URLSset correctly.app.UseForwardedHeaders()behind the platform proxy.- Health checks via
app.MapHealthChecks("/healthz"). - Structured logging to the platform's log pipeline.
- Consider native AOT only after confirming your dependencies support it.
References
- [ASP.NET Core hosting and deployment](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/)
- [.NET native AOT](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/)
- [ASP.NET Core in containers](https://learn.microsoft.com/en-us/dotnet/core/docker/build-container)
- [Forwarded Headers Middleware](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer)
- [EF Core migrations](https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/)
---
Building ASP.NET Core with EF Core on Postgres? PandaStack's free tier wires the database in for you and runs your container in minutes. Try it at [dashboard.pandastack.io](https://dashboard.pandastack.io).