Back to Blog
Tutorial

How to Deploy an ASP.NET Core Application in 1 Minute

Daniel Brooks6 min read
How to Deploy an ASP.NET Core Application in 1 Minute

ASP.NET Core is Microsoft's cross-platform framework for building modern web applications and APIs. It runs on Linux, macOS, and Windows with near-native performance thanks to the Kestrel web server. The framework powers everything from lightweight microservices to enterprise-scale distributed systems.

With Out Plane, you can deploy your ASP.NET Core application in under a minute — no Windows Server or IIS required. This guide shows you exactly how.

What You'll Need

Before starting, make sure you have:

  • .NET 8 SDK installed on your machine
  • A GitHub account
  • An ASP.NET Core application in a GitHub repository
  • A Dockerfile in your project root

Don't have .NET installed? Download it from dotnet.microsoft.com:

  • Windows: Download the SDK installer from dotnet.microsoft.com and run it. Verify with dotnet --version in PowerShell.
  • macOS: Use brew install dotnet-sdk or download the PKG installer from dotnet.microsoft.com
  • Linux: Run sudo apt install -y dotnet-sdk-8.0 (Ubuntu/Debian) or follow the instructions for your distribution at dotnet.microsoft.com

Once .NET is installed, create a project folder:

bash
dotnet new webapi -n MyWebApi --use-controllers false
cd MyWebApi

If you don't have an ASP.NET Core app yet, use our example below.

Quick Start: Sample ASP.NET Core Application

Here's a minimal ASP.NET Core application using the Minimal API pattern. Create a new project:

bash
dotnet new webapi -n MyWebApi --use-controllers false
cd MyWebApi

Replace Program.cs with a simple API:

csharp
var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseUrls("http://0.0.0.0:8080");

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.MapGet("/", () => new
{
    Message = "Hello from ASP.NET Core!",
    Status = "running"
});

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

var items = new List<object>
{
    new { Id = 1, Name = "Item One" },
    new { Id = 2, Name = "Item Two" },
    new { Id = 3, Name = "Item Three" }
};

app.MapGet("/api/items", () => items);

app.MapGet("/api/items/{id}", (int id) =>
{
    var item = items.FirstOrDefault(i => ((dynamic)i).Id == id);
    return item is not null ? Results.Ok(item) : Results.NotFound(new { Error = "Item not found" });
});

app.Run();

Alternatively, you can configure the port using an environment variable instead of hardcoding it. Remove the builder.WebHost.UseUrls() line and set ASPNETCORE_URLS=http://+:8080 in your environment or Dockerfile.

Test your application locally:

bash
dotnet run

Visit http://localhost:8080 in your browser. You should see the JSON response.

Add a Dockerfile

ASP.NET Core applications on Out Plane require a Dockerfile. Create a Dockerfile in the project root using a multi-stage build:

dockerfile
# Build stage
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/publish

# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine AS runtime

WORKDIR /app

COPY --from=build /app/publish .

EXPOSE 8080

ENV ASPNETCORE_URLS=http://+:8080

ENTRYPOINT ["dotnet", "MyWebApi.dll"]

This produces a production-ready image under 100MB. The SDK image is only used during the build stage and discarded from the final image. The Alpine-based runtime image keeps the footprint small.

Push this code to a GitHub repository, and you're ready to deploy.

Deploy in 3 Steps

Step 1: Connect Your Repository

  1. Go to console.outplane.com
  2. Sign in with your GitHub account
  3. Select your ASP.NET Core repository from the list

Out Plane detects the Dockerfile and configures the build process automatically.

Step 2: Configure Your Application

Configure the following settings in the create application form:

Build Method

Select how Out Plane should build your application:

  • Dockerfile (Required for .NET): Uses the multi-stage Dockerfile above to build and package your application. This is the recommended and required approach for ASP.NET Core applications.

Basic Settings

  • Port: Set to 8080
  • Branch: Select main or your preferred branch
  • Region: Choose the region closest to your users (default: Nuremberg)

Environment Variables (Optional)

Add environment-specific configuration using the Add button or Raw Edit for bulk entry:

text
ASPNETCORE_ENVIRONMENT=Production

For more complex applications, you might add variables like database connection strings or API keys.

Step 3: Deploy

Click Deploy Application and watch the build process:

  1. Queued → Waiting for resources
  2. Building → Restoring NuGet packages and compiling your application
  3. Deploying → Starting the Kestrel web server
  4. Ready → Your app is live

Once the status shows Ready, your application is live. You can find your application URL at the top of the deployment page. Click the URL to open your ASP.NET Core app in a new tab. SSL is automatically configured.

Production Best Practices

Kestrel Configuration

Kestrel is the default web server for ASP.NET Core and is production-ready. Configure it for optimal performance:

csharp
var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(options =>
{
    options.Limits.MaxConcurrentConnections = 1000;
    options.Limits.MaxRequestBodySize = 10 * 1024 * 1024; // 10MB
    options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(30);
});

There is no need for a reverse proxy like IIS or Nginx when deploying to Out Plane. Kestrel handles production traffic directly.

Health Checks

ASP.NET Core has built-in health check middleware. Use it for comprehensive health monitoring:

csharp
builder.Services.AddHealthChecks()
    .AddCheck("self", () => HealthCheckResult.Healthy())
    .AddNpgSql(builder.Configuration.GetConnectionString("DefaultConnection")!);

var app = builder.Build();

app.MapHealthChecks("/health", new HealthCheckOptions
{
    ResponseWriter = async (context, report) =>
    {
        context.Response.ContentType = "application/json";
        var result = new
        {
            Status = report.Status.ToString(),
            Checks = report.Entries.Select(e => new
            {
                Name = e.Key,
                Status = e.Value.Status.ToString(),
                Duration = e.Value.Duration.TotalMilliseconds
            })
        };
        await context.Response.WriteAsJsonAsync(result);
    }
});

Install the PostgreSQL health check package:

bash
dotnet add package AspNetCore.HealthChecks.NpgSql

Out Plane uses this endpoint to verify your application is ready to receive traffic.

Logging with Serilog

Replace the default logger with Serilog for structured, production-grade logging:

bash
dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Console
csharp
using Serilog;

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseSerilog((context, config) =>
{
    config
        .ReadFrom.Configuration(context.Configuration)
        .WriteTo.Console(outputTemplate:
            "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}");
});

var app = builder.Build();

app.UseSerilogRequestLogging();

Structured logs make it easier to filter and search in Out Plane's log viewer.

Response Compression

Enable response compression to reduce bandwidth and improve response times:

csharp
builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
});

var app = builder.Build();

app.UseResponseCompression();

This compresses JSON responses and static content using gzip and Brotli automatically.

CORS Configuration

If your API serves a frontend on a different domain, configure CORS:

csharp
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowFrontend", policy =>
    {
        policy.WithOrigins("https://yourfrontend.com")
              .AllowAnyHeader()
              .AllowAnyMethod();
    });
});

var app = builder.Build();

app.UseCors("AllowFrontend");

Connecting a Database

Most ASP.NET Core applications need a database. Out Plane provides managed PostgreSQL:

  1. Go to Databases in the sidebar
  2. Click Create Database
  3. Select PostgreSQL version and region
  4. Copy the connection URL

Add the connection URL as an environment variable:

text
DATABASE_URL=Host=host;Port=5432;Database=database;Username=user;Password=password

Use Entity Framework Core to connect to PostgreSQL:

bash
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
dotnet add package Microsoft.EntityFrameworkCore.Design

Create a DbContext:

csharp
using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    public DbSet<Item> Items => Set<Item>();
}

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}

Register the context in Program.cs:

csharp
var connectionString = Environment.GetEnvironmentVariable("DATABASE_URL")
    ?? builder.Configuration.GetConnectionString("DefaultConnection");

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(connectionString));

Run migrations before deploying:

bash
dotnet ef migrations add InitialCreate
dotnet ef database update

For production deployments, apply migrations at startup:

csharp
using (var scope = app.Services.CreateScope())
{
    var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
    db.Database.Migrate();
}

Custom Domain Setup

Replace the default .outplane.app URL with your own domain:

  1. Navigate to Domains
  2. Click Map Domain
  3. Enter your domain (e.g., api.yourdomain.com)
  4. Add the DNS records shown to your domain registrar

SSL certificates are automatically provisioned once DNS propagates.

Monitoring Your Application

After deployment, monitor your ASP.NET Core application:

  • Logs: View real-time application logs including Kestrel request logs and Serilog output
  • Metrics: Track CPU, memory, and network usage
  • HTTP Logs: Analyze incoming requests, response times, and status codes

Access these from the sidebar in your application dashboard.

Troubleshooting

Application Won't Start — Port Binding

Check the port configuration. Make sure you set the port to 8080 in the application settings. Your Dockerfile must include ENV ASPNETCORE_URLS=http://+:8080 and EXPOSE 8080. Alternatively, set builder.WebHost.UseUrls("http://0.0.0.0:8080") in Program.cs.

Build Fails — SDK vs Runtime Image

Use the SDK image for building and the runtime image for running. The mcr.microsoft.com/dotnet/sdk:8.0 image contains the compiler and build tools. The mcr.microsoft.com/dotnet/aspnet:8.0-alpine image contains only the runtime. Do not use the SDK image as your final stage — it is over 700MB.

Missing Dependencies at Runtime

Verify all NuGet packages are restored during build. Make sure dotnet restore runs in your Dockerfile before dotnet publish. If you use native libraries, ensure they are available in the Alpine base image or switch to the Debian-based runtime image (mcr.microsoft.com/dotnet/aspnet:8.0).

Database Migration Errors

Run migrations before or during startup. If you see relation does not exist errors, your database schema is out of date. Either run dotnet ef database update locally against the production database or add automatic migration at startup as shown in the database section above.

Health Check Failures

Verify your health endpoint returns HTTP 200. Out Plane checks /health to determine if your application is ready. If the health check includes database checks, ensure the database connection string is correct and the database is accessible from your application.

Next Steps

Your ASP.NET Core application is now deployed and running in production. Here's what to explore next:

  • Scale your application: Adjust instance types and auto-scaling settings for higher traffic
  • Set up CI/CD: Enable automatic deployments on every git push
  • Add monitoring: Integrate with external monitoring tools via Out Plane's metrics export
  • Deploy microservices: Use Out Plane to deploy multiple .NET services with internal networking

Summary

Deploying an ASP.NET Core application to Out Plane takes three steps:

  1. Connect your GitHub repository
  2. Configure port (8080), environment variables, and Dockerfile build method
  3. Deploy and get your live URL with automatic HTTPS

No Windows Server, no IIS, no manual SSL setup, no infrastructure management. Just push your code and go live.

Ready to deploy your ASP.NET Core application? Get started with Out Plane and receive $20 in free credit. Pay only for what you use with per-second billing.


Tags

aspnet-core
dotnet
csharp
deployment
tutorial
api

Start deploying in minutes

Connect your GitHub repository and deploy your first application today. $20 free credit. No credit card required.