How to deploy an ASP.NET Application with zero downtime

You need 2 servers and a load balancer. Here's in steps:

  1. Turn all traffic on Server 2
  2. Deploy on Server 1
  3. Test Server 1
  4. Turn all traffic on Server 1
  5. Deploy on Server 2
  6. Test Server 2
  7. Turn traffic on both servers

Thing is, even in this case you will still have application restarts and loss of sessions if you are using "sticky sessions". If you have database sessions or a state server, then everything should be fine.


The Microsoft Web Deployment Tool supports this to some degree:

Enables Windows Transactional File System (TxF) support. When TxF support is enabled, file operations are atomic; that is, they either succeed or fail completely. This ensures data integrity and prevents data or files from existing in a "half-way" or corrupted state. In MS Deploy, TxF is disabled by default.

It seems the transaction is for the entire sync. Also, TxF is a feature of Windows Server 2008, so this transaction feature will not work with earlier versions.

I believe it's possible to modify your script for 0-downtime using folders as versions and the IIS metabase:

  • for an existing path/url:
    • path: \web\app\v2.0\
    • url: http://app
  • Copy new (or modified) website to server under
    • \web\app\v2.1\
  • Modify IIS metabase to change the website path
    • from \web\app\2.0\
    • to \web\app\v2.1\

This method offers the following benefits:

  • In the event new version has a problem, you can easily rollback to v2.0
  • To deploy to multiple physical or virtual servers, you could use your script for file deployment. Once all servers have the new version, you can simultaneously change all servers' metabases using the Microsoft Web Deployment Tool.

You can achieve zero downtime deployment on a single server by utilizing Application Request Routing in IIS as a software load balancer between two local IIS sites on different ports. This is known as a blue green deployment strategy where only one of the two sites is available in the load balancer at any given time. Deploy to the site that is "down", warm it up, and bring it into the load balancer (usually by passing a Application Request Routing health check), then take the original site that was up, out of the "pool" (again by making its health check fail).

A full tutorial can be found here.