Zero Downtime Deployments

Here's how I keep the site up while new versions are built

Many months ago, I posted about switching to Kestrel (the official ASP.NET Core server) and that doing so made it super easy to perform blue-green deployments. I even said I'd share the details, and now I'm finally fulfilling that promise!

I'm also going to introduce another one of my open source tools, that I use for just this purpose: LiveSwitcher.

All wrapped up in a nice 5 second package (only slightly faster than how long it actually takes)

0. Initial State

IIS proxying requests to one kestrel instance, while another waits in the wings

A quick walkthrough:

  1. A request from the browser comes in over HTTPS to IIS
  2. A rewrite rule "forwards" the request (locally, over HTTP) to port 5001, where the "blue" instance of this site is running
  3. Kestrel responds to IIS, who in turn "forwards" the response back to the browser

The "green" instance is my "backup" instance. Say I forgot to run tests before deploying, or something equally silly; this is an easy way to get back to a known working state.

1. Stop "Backup" Instance

Same as above, but green is no longer running

The first thing we want to do is stop the "backup" instance. In this case, since IIS is pointing to blue, green is the backup.

How do we know where IIS is pointing? Enter LiveSwitcher!

C:\www> golive{R:1}

At the prompt, we simply run golive (LiveSwitcher's default executable name) without any parameters to see what the current config has.

Now that we know which instance to stop, we just hit Ctrl+C on its console window and it stops. If it was started using LiveSwitcher's run script, it's already primed to restart once upgraded.

2. Upgrade Non-Running Instance

Green is now at v2, still stopped

Now that we have a deployment slot ready to upgrade, we deploy our app to the relevant endpoint. For me that means a Publish from Visual Studio to C:\www\green on my server.

3. Start Stopped Instance

Green is now running v2

Once our code is finished deploying, we just start our app up again on the desired port. Again, if you're using LiveSwitcher's run script, you're good to go here.

At this point, I usually hit it using the private port, both as a final test, and to make sure that everything is cached/jitted.

4. Point To New Instance

IIS is now "forwarding" to the green instance

You may have noticed that we haven't actually done anything to "production" yet. It's just been running along on its own this whole time.


"IIS and server console windows, what year do you think this is?!" Touché.

While the titles of the boxes change, the process is the exact same:

  1. Bring up the new version
  2. Point the front-end to the new version
Docker doesn't look so different!


Thanks to GIFCreator.ME for the gif at the end, and to the Google Charts API for letting me not have to install graphviz!

I'd love to hear how you've automated your deployments to eliminate downtime. Sound off below!