Deploying a .NET 8 Web API on Linux Containers: Zero-Config Guide | Deployxa

.NET 8 is Microsoft's fastest framework yet, and it runs great on Linux. Here is how to deploy a .NET 8 Web API on Deployxa without writing a Dockerfile.

← Back to Dispatch Articles
Engineering Log

Deploying a .NET 8 Web API on Linux Containers: Zero-Config Guide

.NET 8 is Microsoft's fastest framework yet, and it runs great on Linux. Here is how to deploy a .NET 8 Web API on Deployxa without writing a Dockerfile.

Deploying a .NET 8 Web API on Linux Containers

.NET 8 is Microsoft's fastest framework yet, with performance improvements across the board (ASP.NET Core, Entity Framework, JIT compilation). It runs great on Linux, which means you can deploy .NET apps on container platforms like Deployxa without needing a Windows server. But deploying .NET apps has traditionally required writing a Dockerfile (to restore NuGet packages, publish the app, and configure the ASP.NET runtime), configuring the Kestrel web server, and handling the database connection. Deployxa's zero-config engine eliminates all of that. Here is how to deploy a .NET 8 Web API on Deployxa without writing a single Dockerfile.

The direct answer is that Deployxa auto-detects .NET from your .csproj or .sln file and ASP.NET Core from your source code. It configures the build and start commands automatically: the build command publishes the app (dotnet publish -c Release -o /app), and the start command runs the published DLL (dotnet /app/MyApp.dll). The .NET 8 runtime is included in the container, and Kestrel listens on the port specified by the PORT environment variable (via ASPNETCORE_URLS). You do not write a Dockerfile, you do not configure the build, and you do not manage the runtime. The platform handles all of it, just as it does for Go, Rust, and Node.js apps.

Why .NET 8 Is a Great Choice for Enterprise APIs

Three reasons explain why .NET 8 is a great choice for enterprise APIs. First, .NET 8 is fast: ASP.NET Core 8 is one of the fastest web frameworks available, with throughput comparable to Go and Rust. For high-throughput APIs, .NET 8 is a strong choice. Second, .NET has a mature ecosystem: Entity Framework Core (ORM), ASP.NET Core Identity (authentication), SignalR (realtime), and a vast library of NuGet packages. For enterprise apps that need these features, .NET is a natural fit. Third, C# is approachable: it is similar to Java and TypeScript, which means developers can learn it quickly, and AI assistants can generate correct C# code reliably. The result is that .NET 8 is a great choice for enterprise APIs, and Deployxa makes it easy to deploy without Docker expertise.

The trade-off is that .NET has historically been associated with Windows, which made deployment on Linux containers tricky. .NET 8 (and .NET Core before it) runs great on Linux, but some older .NET Framework libraries are Windows-only. For AI-generated apps, this is rarely an issue, because the LLM generates .NET 8 code that is cross-platform by default. For apps that need Windows-specific libraries, a Windows container or VM might be necessary, but Deployxa focuses on Linux containers.

The Architecture: .NET Binary + Postgres

Here is how Deployxa deploys a .NET 8 Web API.

The .NET container

The ingestion service detects .NET from your .csproj file and ASP.NET Core from your source code. It configures the build and start commands:

  • Build command: dotnet publish -c Release -o /app
  • Start command: dotnet /app/MyApp.dll
  • Runtime: .NET 8 SDK (for build) and .NET 8 Runtime (for execution)

The Postgres connection

Your .NET app connects to Postgres via the ConnectionStrings__DefaultConnection environment variable (or DATABASE_URL), which you set in the Deployxa dashboard. The connection is managed by Entity Framework Core or Npgsql, which handles connection pooling automatically.

The reverse proxy

Traefik v3 routes traffic from your custom domain to the .NET container, with automatic SSL via Let's Encrypt. Kestrel (the ASP.NET Core web server) listens on the container's port, and Traefik proxies requests to it.

Step-by-Step: Deploying a .NET 8 Web API

Here is the exact workflow for a typical .NET 8 Web API.

Step 1: Create your .NET 8 Web API

dotnet new webapi -n MyApp
cd MyApp
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
dotnet add package Microsoft.EntityFrameworkCore.Design

Step 2: Configure the database connection

In Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddControllers();

var app = builder.Build();

app.MapControllers();

app.MapGet("/health", () => Results.Ok(new { status = "ok" }));

var port = Environment.GetEnvironmentVariable("PORT") ?? "8080";
app.Run($"http://0.0.0.0:{port}");

Step 3: Create the DbContext and a model

// Data/AppDbContext.cs
using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions options) : base(options) { }
    public DbSet Users => Set();
}

// Models/User.cs
public class User
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
}

Step 4: Configure appsettings.json

{
  "ConnectionStrings": {
    "DefaultConnection": "Host=localhost;Database=mydb;Username=postgres;Password=password"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

Step 5: Push to GitHub

git init
git add .
git commit -m ".net 8 web api"
git remote add origin https://github.com/yourname/MyApp.git
git push -u origin main

Step 6: Connect to Deployxa

In the Deployxa dashboard, connect your repository. Deployxa auto-detects .NET:

[ingest] Detected .NET project
[ingest] Framework: aspnetcore
[ingest] Runtime: dotnet 8.0
[ingest] Build command: dotnet publish -c Release -o /app
[ingest] Start command: dotnet /app/MyApp.dll
[ingest] Port: $PORT

Step 7: Configure environment variables

In the Deployxa dashboard, add ConnectionStrings__DefaultConnection with your Postgres connection string (e.g., Host=your-postgres-host;Database=mydb;Username=user;Password=pass). The double underscore (__) is the standard .NET convention for nested configuration keys in environment variables. The pre-flight scanner will warn you if it is missing.

Step 8: Deploy

Click Deploy. The build restores NuGet packages, compiles the app, and publishes it to /app. The container starts, Kestrel listens on the assigned port, and your API is live within 60 to 90 seconds.

Step 9: Run Entity Framework migrations

After the first deployment, run your database migrations:

dotnet ef database update --project MyApp

You can do this via the Deployxa CLI or by including the migration command in the build process.

Step 10: Add a custom domain

Add a custom domain in the Deployxa dashboard. SSL is provisioned automatically.

Step 11: Verify with deployxa doctor

Run deployxa doctor to verify health. The 14-point readiness engine checks SSL, DNS, environment variables, health endpoints, and container status.

Common Pitfalls and Troubleshooting

The first pitfall is the PORT environment variable. ASP.NET Core apps typically listen on port 5000 or 8080 by default, but Deployxa assigns a dynamic port via the PORT environment variable. The fix is to use Environment.GetEnvironmentVariable("PORT") as shown in the code above, or to set ASPNETCORE_URLS=http://0.0.0.0:$PORT in the start command. The second pitfall is the connection string format. .NET connection strings use a different format from other frameworks (e.g., Host=...;Database=...;Username=...;Password=...), which can cause confusion. The fix is to use the standard Npgsql format and to set it via the ConnectionStrings__DefaultConnection environment variable. The third pitfall is Entity Framework migrations. Migrations should run before the traffic swap, not after. The fix is to include dotnet ef database update in the build command or to run it as a pre-deployment step. The fourth pitfall is the .NET SDK size. The .NET 8 SDK is large (500MB+), which can slow down the build. The fix is to use the .NET 8 Runtime (not the SDK) for the execution stage, which is much smaller. Deployxa's zero-config engine handles this automatically by using a multi-stage build internally. The fifth pitfall is Windows-specific dependencies. If your .NET app uses Windows-specific libraries (e.g., System.Drawing.Common before .NET 6), it will not run on Linux. The fix is to use cross-platform alternatives (e.g., SixLabors.ImageSharp instead of System.Drawing.Common).

Performance: .NET 8 vs Other Frameworks

.NET 8 is one of the fastest web frameworks available, with throughput comparable to Go and Rust. For simple JSON responses, ASP.NET Core 8 is 2 to 3x faster than Node.js (with Fastify) and comparable to Go Fiber. For database-heavy endpoints, the difference is smaller, because the database is the bottleneck. The exact performance depends on the workload, but for most APIs, .NET 8 is fast enough that performance is not a concern. For more on performance, see our article on SPA vs SSR hardware sizing. For a comparison of .NET 8 with Go Fiber and Rust Axum, see our articles on deploying Go Fiber APIs and deploying Rust Axum APIs.

Advanced .NET 8 Patterns

Beyond the basics, .NET 8 Web APIs benefit from several advanced patterns. The first is minimal APIs. .NET 6+ introduced minimal APIs, which let you define endpoints with less boilerplate than controllers. The fix is to use app.MapGet, app.MapPost, etc. for simple endpoints, and controllers for complex ones. The second is dependency injection. .NET's built-in DI container handles service registration and lifetime (singleton, scoped, transient). The fix is to register your services in Program.cs and to inject them via constructor parameters. The third is configuration. .NET's IConfiguration handles configuration from multiple sources (appsettings.json, environment variables, command-line args). The fix is to use the options pattern (IOptions) to bind configuration to strongly-typed classes. The fourth is authentication. .NET's Microsoft.AspNetCore.Authentication.JwtBearer handles JWT authentication. The fix is to configure JWT authentication in Program.cs and to use the [Authorize] attribute on protected endpoints. The fifth is testing. .NET's xUnit and Moq libraries make it easy to write unit tests. The fix is to write tests for your handlers and to run them in CI. The sixth is OpenAPI documentation. .NET's Swashbuckle library generates OpenAPI documentation from your code. The fix is to add Swashbuckle to your project and to configure it in Program.cs. The seventh is observability. .NET's OpenTelemetry library provides structured logging, metrics, and distributed tracing. The fix is to use OpenTelemetry and to export to an OTLP-compatible backend. For more on .NET deployment, see our articles on deploying Go Fiber APIs and deploying Rust Axum APIs.

Conclusion: .NET 8 on Linux Without the Dockerfile

.NET 8 is Microsoft's fastest framework yet, and it runs great on Linux. Deployxa's zero-config engine makes it easy to deploy .NET 8 Web APIs without writing a Dockerfile, configuring Kestrel, or managing the runtime. Stop writing Dockerfiles for .NET apps and start shipping.

Ready to deploy your .NET 8 Web API? Drag your project to Deployxa Drop for an instant live preview, or install the CLI with npm i -g @deployxa/cli and deploy from your terminal. For more on polyglot deployment, see our articles on deploying Go Fiber APIs and deploying Rust Axum APIs. Learn about deploying Django + React and running BullMQ background workers in our companion articles. Explore our free developer tools to speed up your workflow.

Ready to deploy with Deployxa?

Deploy your apps globally with automatic SSL and AI diagnostics.

Start Free Now