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
- Web Packaging - Offline vs. Online
- From VS 2010
- From IIS Manager
- Web.Config Transformation
- Transform Syntax
- Locator Syntax
- Why not XSLT?
- Deploying
- Command Line
- What If Switch
- From IIS
- Content Sync
- DB Deployment
- Scripting Source DB
- Adding custom SQL Scripts
- Download and Deployment of Open Source
- One Click Publish
- Using Web Deploy (Ms Deploy) WMSVC
- Using Web Deploy (Ms Deploy) Remote Agent
- Using InProc Web Deploy (Ms Deploy)
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
© 2010 Scott Hanselman. All rights reserved.