ASP.NET Core  

Zero Downtime Deployment Strategies for ASP.NET Core Apps

1. Introduction

For any production web application, downtime is costly — users lose access, transactions fail, and trust drops.
When you deploy a new version of your ASP.NET Core app, your goal should be clear: users should never experience downtime.

This approach is called Zero Downtime Deployment (ZDD) — meaning your application stays live and responsive even while new code is being deployed or old instances are being replaced.

In this article, we’ll explore step-by-step strategies to achieve Zero Downtime Deployment for ASP.NET Core applications hosted on IIS (Windows Server), using CI/CD pipelines with Jenkins or GitHub Actions.
We’ll also look at practical configuration tips, code samples, and a technical workflow diagram.

2. Why Zero Downtime Matters

Imagine you deploy a critical ASP.NET Core app for your client. The deployment takes 2 minutes. During that time:

  • The IIS app pool restarts.

  • Active user sessions are lost.

  • New requests return a 503 – Service Unavailable error.

This might sound minor, but if 1000+ users are active, even a few seconds of downtime can impact business operations.

Zero Downtime Deployment ensures

  • No 503 or restart interruptions.

  • Sessions and active requests remain stable.

  • Rollbacks are fast if something breaks.

  • Continuous delivery becomes truly continuous.

3. Core Idea Behind Zero Downtime

Zero Downtime Deployment is built on three main pillars:

  1. Multiple instances or slots of the same app (old + new).

  2. Load balancing or traffic redirection between instances.

  3. Atomic switch-over once the new version is verified.

In IIS-based environments, this can be achieved through:

  • Blue-Green deployment strategy

  • Rolling updates using multiple servers

  • Deployment slot swapping (if using Azure App Services)

  • Load balancer (ARR, Nginx, or hardware-based)

4. Technical Workflow Flowchart

Here’s the technical workflow that shows how a typical Zero Downtime Deployment pipeline works in IIS with Jenkins or GitHub Actions:

            ┌────────────────────────────┐
            │   Developer commits code   │
            └────────────┬───────────────┘
                         │
                         ▼
              ┌──────────────────────┐
              │ CI/CD Pipeline (Jenkins│
              │ or GitHub Actions)     │
              └────────────┬──────────┘
                           │
               ┌───────────▼────────────┐
               │  Build & Test Project  │
               │  dotnet publish        │
               └───────────┬────────────┘
                           │
        ┌──────────────────▼────────────────────┐
        │  Deploy to Staging (Green Environment)│
        │  IIS site: myapp-green                │
        └──────────────────┬────────────────────┘
                           │
                           ▼
               ┌───────────────────────┐
               │ Smoke Test / Health   │
               │ Check Green Site      │
               └───────────┬───────────┘
                           │
         ┌─────────────────▼────────────────┐
         │ If Healthy → Switch Load Balancer│
         │ from Blue → Green                │
         └─────────────────┬────────────────┘
                           │
                           ▼
                 ┌──────────────────┐
                 │  Monitor Traffic │
                 │  Rollback if Fail│
                 └──────────────────┘

5. Step-by-Step Implementation

Let’s break down the process for ASP.NET Core + IIS + Jenkins setup.

Step 1: Prepare IIS with Blue-Green Sites

You need two IIS sites:

  • myapp-blue → current production version

  • myapp-green → staging or upcoming version

Each point to a different physical folder, e.g.

C:\inetpub\wwwroot\myapp-blueC:\inetpub\wwwroot\myapp-green

Both should

  • Run on the same application pool.

  • Have the same bindings (except port if on the same server).

  • Share the same database and configuration (except for version differences).

Step 2: Build and Publish the ASP.NET Core App

In Jenkins, your build stage should execute the following:

dotnet clean
dotnet restore
dotnet build --configuration Release
dotnet publish -c Release -o ./publish

This generates the compiled files ready to deploy.

Step 3: Deploy to Green Environment

Copy the published output to the myapp-green folder.

Example PowerShell command (used in Jenkins pipeline):

Copy-Item -Path "C:\Jenkins\workspace\MyApp\publish\*" `
          -Destination "C:\inetpub\wwwroot\myapp-green" `
          -Recurse -Force

Then restart only the myapp-green site:

Restart-WebAppPool "MyAppPool"
Start-WebSite "myapp-green"

Step 4: Health Check and Validation

Run a simple smoke test to confirm that the Green site is working fine:

curl http://localhost:8081/health

Your ASP.NET Core app should have a health endpoint like this:

// In Program.cs
app.MapGet("/health", () => Results.Ok("Healthy"));

If the result is “Healthy,” you can safely switch traffic.

Step 5: Switch Traffic from Blue → Green

You can switch manually or automatically.

Option 1: DNS Switch (Simple but Slower)
Update your DNS or reverse proxy to point from myapp-blue to myapp-green.

Option 2: Application Request Routing (ARR)
If you use IIS ARR as a load balancer, modify your routing rules:

<rule name="BlueToGreenSwitch" enabled="true">
  <match url="(.*)" />
  <action type="Rewrite" url="http://myapp-green/{R:1}" />
</rule>

Option 3: Jenkins Automated Step

stage('Switch Traffic') {
    steps {
        powershell """
        Import-Module WebAdministration
        Stop-Website 'myapp-blue'
        Start-Website 'myapp-green'
        """
    }
}

This ensures that your users seamlessly move to the new version.

Step 6: Monitor and Rollback if Needed

If your monitoring detects any issue:

  • Stop myapp-green

  • Restart myapp-blue

  • Notify the DevOps/QA team

Rollback command:

Stop-Website 'myapp-green'
Start-Website 'myapp-blue'

6. Example Jenkinsfile for Zero Downtime Deployment

Below is a simplified Jenkinsfile demonstrating the stages we discussed:

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                bat 'dotnet clean'
                bat 'dotnet restore'
                bat 'dotnet publish -c Release -o publish'
            }
        }
        stage('Deploy to Green') {
            steps {
                powershell '''
                Copy-Item -Path "publish/*" -Destination "C:\\inetpub\\wwwroot\\myapp-green" -Recurse -Force
                Restart-WebAppPool "MyAppPool"
                Start-Website "myapp-green"
                '''
            }
        }
        stage('Health Check') {
            steps {
                script {
                    def response = bat(script: 'curl http://localhost:8081/health', returnStdout: true).trim()
                    if (!response.contains("Healthy")) {
                        error("Health check failed for Green site")
                    }
                }
            }
        }
        stage('Switch Traffic') {
            steps {
                powershell '''
                Stop-Website "myapp-blue"
                Start-Website "myapp-green"
                '''
            }
        }
    }
}

7. ASP.NET Core Configuration for Smooth Restarts

To prevent interruptions during pool recycling or restarts, configure graceful shutdown in your ASP.NET Core app:

builder.WebHost.ConfigureKestrel(options =>
{
    options.AddServerHeader = false;
    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
});

app.Lifetime.ApplicationStopping.Register(() =>
{
    Console.WriteLine("App is shutting down gracefully...");
});

This ensures ongoing requests complete before shutdown.

8. Monitoring After Deployment

Once your new version (Green) is live:

  • Use Application Insights or ELK (Elastic Stack) for real-time logs.

  • Monitor response time, error rates, and CPU/memory usage.

  • Keep the Blue site in standby for at least a few hours for easy rollback.

Example Application Insights setup in Program.cs:

builder.Services.AddApplicationInsightsTelemetry();

9. Best Practices for Zero Downtime in IIS + Jenkins

  1. Always keep two environments (Blue & Green).

  2. Automate smoke testing after each deployment.

  3. Use load balancer session affinity if your app maintains user sessions.

  4. Externalize configurations using appsettings.Production.json or environment variables.

  5. Backup your database schema before deployment.

  6. Use warm-up scripts to pre-load caches.

  7. Document rollback procedures clearly.

10. Real-World Use Case

At SilverXis Pvt Ltd, a team implemented zero-downtime deployment for a large ASP.NET Core + Angular ERP system hosted on IIS.

Earlier, users experienced brief service interruptions during release updates.
After implementing the Blue-Green strategy with Jenkins, deployment became completely seamless —
QA tested the new build on Green while Blue remained live, and a single PowerShell step switched production traffic instantly.

The result:
✅ 0 downtime
✅ Faster rollbacks
✅ Higher confidence during release windows

11. Summary

StageDescriptionTools Used
Code CommitDeveloper pushes to GitGitHub
CI BuildBuild, Test, PublishJenkins + .NET CLI
Deploy GreenCopy files, start sitePowerShell + IIS
Health CheckVerify Green environmentCurl / API test
Switch TrafficBlue → GreenJenkins + IIS
Monitor & RollbackObserve healthApp Insights / ELK

12. Conclusion

Zero Downtime Deployment isn’t just a DevOps luxury — it’s a business necessity.
With ASP.NET Core, IIS, and Jenkins, achieving it is both practical and reliable.

By following a Blue-Green deployment model, automating through Jenkins CI/CD, and implementing proper health checks and monitoring, your application can be deployed anytime — without a single second of downtime.