I did three talks at Mix 10 this year, and I'm going to do blog posts for each one, sharing what I talked about and some code if it's useful.
I did a talk on Deployment called "Web Deployment Made Awesome: If You're Using XCopy, You're Doing It Wrong."
You can download the talk here, or watch it online:
VIDEO Download: MP4 Video, Windows Media Video, Windows Media Video (High)
I always try to sneak cooler titles into conferences if I can. It's better than "WEB101: Deploying Websites using Microsoft Visual Studio 2010's WebDeploy OneClick Publish Wizard Super Karate Monkey Death Car September CTP R2." Well, maybe not way better, but still.
Here's an outline of what Deployment Related topics I tried to cover
Here's some cool highlights about WebDeployment in Visual Studio 2010. You can right-click on your web.config and click "Add Config Transforms."
When you do this, you'll get a web.debug.config and a web.release.config. You can make a web.whatever.config if you like, as long as the name lines up with a configuration profile. These files are just the changes you want made, not a complete copy of your web.config.
You might think you'd want to use XSLT to transform a web.config, but while they feels intuitively right it's actually very verbose.
Here's two transforms, one using XSLT and the same one using the XML Document Transform syntax/namespace. As with all things there's multiple ways in XSLT to do this, but you get the general idea. XSLT is a generalized tree transformation language, while this deployment one is optimized for a specific subset of common scenarios. But, the cool part is that each XDT transform is a .NET plugin, so you can make your own.
<?xml version="1.0" ?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy></xsl:template><xsl:template match="/configuration/appSettings"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> <xsl:element name="add"> <xsl:attribute name="key">NewSetting</xsl:attribute> <xsl:attribute name="value">New Setting Value</xsl:attribute> </xsl:element> </xsl:copy></xsl:template></xsl:stylesheet>
Or the same thing via the deployment transform:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <appSettings> <add name="NewSetting" value="New Setting Value" xdt:Transform="Insert"/> </appSettings></configuration>
Now, to express this concretely, here's my new NerdDinner web.debug.config:
<?xml version="1.0"?><!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 --><configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <system.web> <customErrors mode="Off" xdt:Transform="Replace"> </customErrors> </system.web> </configuration>
and here's the web.release.config. Note that I update connectionStrings, change appSettings (in this case, Twitter library stuff), and change the system.web section, turning on customErrors and removing the debug attribute.
<?xml version="1.0"?><!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 --><configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <connectionStrings> <add name="ApplicationServices" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" connectionString="foobar" providerName="System.Data.SqlClient" /> <add name="NerdDinnerEntities" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" connectionString="foofoo" providerName="System.Data.EntityClient" /> </connectionStrings> <appSettings> <add key="twitterConsumerKey" value="#$@*)$(@*$)@(*)$(#@*" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" /> <add key="twitterConsumerSecret" value="2340928402" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" /> </appSettings> <system.web> <customErrors mode="On" defaultRedirect="/Dinners/Trouble" xdt:Transform="Replace"> <error statusCode="404" redirect="/Dinners/Confused" /> </customErrors> <compilation xdt:Transform="RemoveAttributes(debug)" /> </system.web></configuration>
This is just config transforms, which is a small part of the whole deployment process. I also showed the packaging process and the package deployment that can happen with one-click from within Visual Studio, or can be initiated from IIS, or at the command-line from your Continuous Integration solution.
The WebDeploy packaging and deployment solution is also what the Web Platform Installer uses. It's all the same engine. This screenshot is me importing an open source application directly from a zip file. Note it's more than just what files to use, it's also setting ACLs (Access Control Lists, or permissions) and creating an IIS application. This just scratches the surface.
Check out my talk, I hope it helps you out. There's more content in that 60 min talk than I could easily put in a single blog post.
Related Links
* the command line* your own apps via API* vs2010* IIS manager* msbuild, etc, etc...
1. Can I deploy an upgrade with zero downtime?
I doubt this will affect your scenario, if you truely do need zero downtime, then you need to load balance, when deploying, have the load balancer point at one server only until the other is up and then vice versa. There is just too many scenarios too consider for automagic 0% zero downtime switch over, what about instances conflicting in same app pool, what about locks on files (logs) plus a dozen other things that Im sure others will chine in on etc., only a simple site it might work. If you cant afford or justify the load balancer and multiple servers you need to determine if you as a software developer or infrastructure manager can accept from your client a 0% downtime SLA given your budget/resources, at this point you have to stand up and say "sorry, no money, no can do".
msbuild mytest_deploy.wdproj /t:Package
<runtime xdt:Transform="Replace"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="bin;Clients/_Assemblies"/> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>
Scott at DevReach in Bulgaria in October
Developer Stand up Comedy - Coding 4 Fun
TechDays/DevDays Netherlands and Belgium:
Posts by Category Posts by Month
Greatest Hits Dev Tools List