One of the things I’m keen on getting setup is a great solution for one click deployment. Lucky for me one of Microsoft’s new tools is the Web Deployment Tool, but as it’s very new information on or about it is very limited and it’s quite complicated to figure out. Fortunately once you do figure it out, it’s remarkably easy to use, as long as you have a little server knowledge and know how to use IIS.
I’m using Visual Studio 2008. This is apparently a lot easier in VSTS 2010, but I’m not all that keen on getting the Beta to work on our production web site, so I’ll be sticking with 2008 for some time. You don’t need to do anything in particular to Visual Studio however, just install it.
Web Deployment Project
This first came out for Visual Studio 2005 and is a great tool. Scott Gu has the best tutorial I know of on how to use it, you can find that here. It’s a tutorial for 2005, but it works just the same in 2008.
Web Deployment Tool
The only thing I can say about this is that it is very difficult to use. Not because the tool is all that complicated, in fact it’s remarkably simple, but because there are so many uses for it and so little information yet. In its defence, it’s a new tool and currently only in BETA so I shouldn’t complain. It is, however, very useful once you understand how it can work for you.
What I did
Assuming you already have a project setup in Visual Studio 2008 (or 2005) this should be pretty easy. Read Scott Gu’s tutorial first on Web Deployment Projects because I’m going to assume that you know a little about these first.
1. Create a Web Deployment Project
Add a web deployment project to your project. If you’re developing a web site, just right click the website and choose the Add Web Deployment Project option. You’ll get a new project with no files and a default name of <YourWebSite>_deploy.
As you’ve ready through Scott Gu’s tutorial you’ll know a little about this file. One of the things I find most useful about it is the ability to overwrite sections of your web.config during the build deployment. You will need a config file for each section you want to replace, though I expect it’s uncommon for there to be more than 4-6 of these sections. I created a subdirectory called config and stored all my config files in there naming them after the section they were replacing, I.E. ProdAppSettings.config.
You’ll notice I’ve got a ProductionLog4Net.config file. This didn’t actually work and I couldn’t get the default tool to replace this for me, if anyone reading this knows how to get the WebDeploymentProject to replace log4Net config sections please let me know.
2. Setup the Web Deployment Tool
This is the hardest step, mostly due to lack of information on how this tool works and most importantly how it can be useful to deploy directly from visual studio. Firstly you’ll need to download the latest version of the tool, I used the 1.0 RC. You’ll need to install two copies of this, one on your local machine and one on the server you’re going to deploy to. On your local, you can install as minimal as you like because all you really need is MSDEPLOY.
On the remote machine, your deployment server (production or test or whatever you call it), you’re going to need to install everything. You need the Remote Agent Service and the IIS 7.0 Deployment Handler. If you really want you could probably get away without the PowerShell Cmdlets or the UI module for IIS Manager, but I think you’ll find use for them at some point.
Once the install is done you’re going to need to start a couple of services
The Web Deployment Agent Service and the Web Management Service should enable you to deploy from a remote location. Now it’s best to test this, on your local machine fire up the Msdeploy Command Console, if you’ve in stalled the Web Deployment Tool locally with defaults you’ll find it under IIS 7.0 Extensions in the Programs list. All it is really is a command prompt pointing at the right directory, so if you can’t find it I’m sure you’ll figure something out.
3. MSDeploy – Confusing
So MSDeploy is a little confusing to start with, lots of options and not much documentation. I’ve used it in a particular way, but you can use it in many many ways. What is boils down to is a synchronisation tool that you can use to synchronise files between directories and web servers (which really are just virtual directories anyway). Run it without any commands and it’ll give you the idea.
What I want is to synchronise my local output from my Web Deployment Project with my remote web server. This is easy.
The command is:
msdeploy -verb:sync -source:iisApp=C:\MyDir\MySite -dest:iisApp=<Website>, computerName=<RemoteDeploymentServer>, username=<UserWithAccess>, password=<Password> -skip:objectName=dirPath,absolutePath=<DirectoryYouDontWantToSync>-skip:objectName=dirPath,absolutePath=<DirectoryYouDontWantToSync2>
The sync verb will tell the deployment tool to synchronise the local directory and the remote one. The source is your local directory, the destination is the IIS website on the remote server. You can skip directories that you don’t wan to sync, otherwise those directories would be deleted during the sync.
At this point I’d try it with a test from the out put of your Web Deployment Project. I didn’t run into any problems once I understood how it worked, however you might. I imagine the most likely problem is going to be a firewall restriction, however if you don’t have that it should work. If not let me know.
4. One Click Deployment
I don’t want to have to leave visual studio and run some silly script just to deploy my site. I want to do it with one click, or even better, as part of my build! Well the web deployment project is great for this.
Choose “Open Project File” and find at the end of the XML the AfterBuild section. Then just create an Exec command and set the Command to your msbuild command created above.
<Target Name="AfterBuild"> <Exec Command="msdeploy -verb:sync -source:iisApp=$(OutputPath) -dest:iisApp=MyWebSite,computerName=DeploymentServer,username=DeploymentUser,password=password -skip:objectName=dirPath,absolutePath=DynamicImages -skip:objectName=dirPath,absolutePath=DynamicDirectory" ContinueOnError="false"> </Exec> </Target>
$(OutputPath) is the output path of your Web Deployment Project.
5. Run it!
If everything went according to plan, when you build it will now deploy your project to your web server. There are a few things you should finish off before you’re done though.
Firstly, I would only set the web deployment project to build when your are in release mode.
That way your debug build are not deployed anywhere. You could also not build it at all so that deployment is only done when you build the deployment project specifically.
Also, every time you do a build it’s going to release all your source every time. This is because the output files for your project will be replaced every time with new versions. Easy change really, just tell your web deployment project not to merge the output and you’ll be fine.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugSymbols>false</DebugSymbols> <OutputPath>removed from paste</OutputPath> <EnableUpdateable>true</EnableUpdateable> <UseMerge>false</UseMerge> <SingleAssemblyName>MyWebsite.dll</SingleAssemblyName> <AssemblyPrefixName> </AssemblyPrefixName> <ContentAssemblyName> </ContentAssemblyName> <DeleteAppCodeCompiledFiles>true</DeleteAppCodeCompiledFiles> <UseWebConfigReplacement>true</UseWebConfigReplacement> </PropertyGroup>
It will still deploy your DLL files every time because they are built with every rebuild, but with shadow copy in IIS this is not an issue.
So I now have one click deployment to my remote web server, right from inside visual studio. I suppose it’s a little dangerous because any developer can now deploy right into the live environment, but as this is a small company here there is little risk of that. If you don’t like that idea, you can setup a staging environment where you do deploy to and use the Web Deployment Tool to allow on demand synchronisation between the staging environment and the live one.