There are many ways to deploy an ASP.NET web application. If you have done any research on the topic, you have probably heard Scott Hanselman tell you that You’re Doing It Wrong.
His post gives a very good overview of Microsoft’s Web Deploy technology and it’s many uses. I have used Web Deploy in the past and it works great. It especially works great if you are building an internal application that is deployed to a limited number of servers (ie. Dev / Test / Production). In this case, you can easily configure your build process to automatically make changes to your web.config and deploy to your various servers.
There is one scenario where I struggle with the web deployment process. I initially thought it was a very rare situation, but I have seen this three times. Either I am incredibly lucky (unlucky?), or this is actually more common than I thought.
Deploying a Web Application to Client Sites
Here is the scenario: You work for a company that builds a commercial product. The product is built using ASP.NET and (obviously) hosted in IIS. Here’s the screwy part…the application is not hosted on your own server. Instead, the application is deployed internally at each individual client site.
Why would you ever do that!?!?!? As it turns out, there are some good reason. There is a certain class of application, within a certain class of client that makes companies nervous about not having complete ownership over the data and environment of the application. Think banks, legal firms, telecom… These apps might not require huge servers or web farms and the database could easily be hosted on the same server as the website. The number of clients might vary anywhere from ten to hundreds.
What are your options
Use Web Deploy as much as possible!
For your internal deployments, use Web Deploy to automatically deploy to your Dev/Test/Prod servers as part of your build process.
For external client deployments, you probably want give the client some sort of package that will allow them to manage the initial install of the application. You probably have a large number of clients and a small team. You can’t possibly do all the installs yourself. The install might involve creating a database, configuration the application in IIS, deploying the application files to IIS, adjusting file and folder permissions, and countless other configuration tasks. Likewise when distributing updates to the application, you would like to provide the client with a package that will automate the update for them. This includes upgrading the database and the web application files.
Start by using web deploy to create a package for your application. This should be the same package as you used for your internal deployments. You should add any parameters that you might want the user to enter during the install process. This might include database connection string information and any other application settings necessary at install time. You can read more about parameterizing your web deploy packages here.
Next, you could create a package that would be distributed and installed using Microsoft’s Web Platform Installer. This walktrough will take you through the whole process of building the package and custom feed that you can publish to your clients. This option would work well for some applications, but I have found that with some legacy applications it can be difficult to accomplish everything you want to do using only Web Deploy and Web Platform Installer. For example, if your application was built using a database other than SQL Server, how do you manage your database creation and upgrades. Even some of the IIS configuration steps can be difficult to accomplish using Web Deploy.
Another option would be to use a deployment management tool such as Octopus Deploy. This is a great tool for managing your deployments, but it doesn’t work great for this scenario. First, the clients we mentioned above will perceive this tool as a security risk. I don’t necessarily agree with that assessment, but this has been my experience. Second, if you are managing 100s of deployments, it would mean managing 100s of configurations inside your deployment server. For each of those deployments, you would need to know the details of the clients database connection information and all their configuration settings. Chances are, you don’t really care what the name of your client’s database server is.
Yet another option would be to create an MSI using WIX or Install Shield. This is totally do-able and completely flexible, but rather painful to implement and maintain. I find myself needing to re-learn the technology every time I try to create an MSI.
Finally, you could take hybrid approach. Create a simple WPF or Win Forms application that looks something like an installer. Since it is now your own .NET code, you can add whatever logic you need to the install process. Using the Microsoft.Web.Administration.aspx) assembly, you can easily configure application pools, create applications, and basically do anything that you can do using IIS Manager. You could even detect when your application is already installed on the server by inspecting IIS to see what applications are there. You could build some nice forms to let the user select any necessary options. Best of all, you can still use Web Deploy to deploy the application in to IIS using the Microsoft.Web.Deployment.aspx) assembly.
For this very unique type of deployment, I find the hybrid approach works the best. Leverage Web Deploy for as much of the deployment as possible, then build a nice installer-like wrapper using WPF or Win Forms. This option gives you the best level of flexibility and will provide the best install experience possible for your clients.
NOTE: I am planning on building a sample application to demonstrate this concept and will update this post when it is completed.