Skip to content

Aspnet Deployment

DodaTech 4 min read

title: ASP.NET Core Deployment — Complete Guide to Production Deployment description: 'Learn ASP.NET Core deployment: IIS, Kestrel behind Nginx, Azure App Service, environment configuration, CI/CD pipelines, SSL certificates, and monitoring.' date: 2026-06-28 lastmod: 2026-06-28 weight: 33 tags: [backend, aspnet]


ASP.NET Core deployment involves configuring the application for production, choosing a hosting strategy, setting up reverse proxies, managing environment variables, and implementing CI/CD pipelines.

## What You'll Learn

By the end of this tutorial, you'll deploy ASP.NET Core to IIS, Linux with Nginx, Azure App Service, configure production settings, set up CI/CD with GitHub Actions, and monitor deployed apps.

## Real-World Use

A CI/CD pipeline builds ASP.NET Core, runs tests, pushes to Azure Container Registry, and deploys to Azure App Service. Staging and production slots enable zero-downtime deployments.

## Deployment Learning Path

```mermaid
flowchart LR
  A[Docker] --> B[Deployment]
  B --> C[Reference]
  B --> D{You Are Here}
  style D fill:#f90,color:#fff

Linux with Nginx

# Publish application
dotnet publish -c Release -o /var/www/myapp

# Nginx configuration
sudo nano /etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name myapp.example.com;
    location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}
# Configure systemd service
sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=MyApp ASP.NET Core App
[Service]
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/dotnet /var/www/myapp/MyApp.Web.dll
Restart=always
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=myapp-app
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=ASPNETCORE_URLS=http://localhost:5000
[Install]
WantedBy=multi-user.target

Azure App Service

# Deploy using azure cli
az webapp up --name myapp-api --runtime "DOTNET|8.0" --sku F1

# Or deploy from GitHub
# Configure GitHub Actions workflow
name: Deploy to Azure
on:
  push:
    branches: [main]
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '8.0'
      - name: Build and Publish
        run: |
          dotnet restore
          dotnet publish -c Release -o ./publish
      - name: Deploy to Azure
        uses: azure/webapps-deploy@v3
        with:
          app-name: myapp-api
          publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
          package: ./publish

Production Configuration

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Kestrel": {
    "Endpoints": {
      "Http": { "Url": "http://localhost:5000" }
    }
  }
}
// Program.cs - production hardening
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/error");
    app.UseHsts();                    // HTTP Strict Transport Security
    app.UseHttpsRedirection();
}
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

Common Mistakes

1. Not Configuring Forwarded Headers

Behind Nginx/Azure, the app needs forwarded headers to get the original client IP and protocol.

2. Debug Mode in Production

Setting ASPNETCORE_ENVIRONMENT=Development exposes detailed errors. Always use Production.

3. Not Using a Reverse Proxy

Kestrel directly exposed to the internet lacks security features of Nginx/IIS. Use a reverse proxy.

4. Ignoring Connection String Management

Connection strings in appsettings.json get committed to source control. Use environment variables or Azure Key Vault.

5. No Health Checks

Without health checks, load balancers send traffic to unhealthy instances. MapHealthChecks and configure probes.

Practice Questions

1. Why use a reverse proxy (Nginx) in front of Kestrel?

Nginx provides SSL termination, static file serving, rate limiting, and security headers. Kestrel focuses on ASP.NET Core.

2. How do you deploy ASP.NET Core to a Linux server?

Publish with dotnet publish -c Release, copy to server, configure Nginx reverse proxy, set up systemd service.

3. What is the purpose of the ForwardedHeaders middleware?

Restores the original client IP and scheme when the app runs behind a reverse proxy.

4. How do you set up CI/CD for ASP.NET Core?

Use GitHub Actions, Azure DevOps, or Jenkins. Build, test, publish, and deploy on push to main branch.

5. Challenge: Create a complete production deployment with Nginx, systemd, and HTTPS.

# Steps:
# 1. dotnet publish -c Release
# 2. Copy to /var/www/myapp
# 3. Configure Nginx reverse proxy with SSL
# 4. Create systemd service
# 5. sudo systemctl start myapp

FAQ

Can I deploy ASP.NET Core to a shared hosting environment?

Yes. Publish as a self-contained app and use the host's IIS management tools.

What is the difference between Kestrel and IIS?

Kestrel is the cross-platform web server built into ASP.NET Core. IIS is a full-featured Windows web server that acts as a reverse proxy.

How do I deploy database migrations?

Run dotnet ef database update as a deployment step, or generate idempotent SQL scripts.

What is the best hosting option for ASP.NET Core?

Azure App Service for ease. Linux VPS for control. Containers/Kubernetes for scalability.

How do I handle application updates?

Zero-downtime: deploy to staging slot, swap with production. For single-server: use a rolling restart.

Mini Project: Deploy to Linux VPS

Publish and deploy an ASP.NET Core API with Nginx and systemd.

dotnet publish -c Release -o publish/
scp -r publish/ user@server:/var/www/myapp
ssh user@server
sudo systemctl enable myapp
sudo systemctl start myapp
sudo nginx -t && sudo systemctl reload nginx

What's Next

ASP.NET Core Reference Backend Overview

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro