Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split deployment of web application between web and image servers

I have a single ASP.NET 3.5 web application project. I would like to deploy most of it to my web server, but I would like to deploy CSS, images, and JavaScript to a second "image server".

How can I do this using Web Deploy, or even the "publish" feature of Visual Studio 2010 and above?


Some have asked what I have tried. I haven't tried anything, because I don't know of anything to try.

I've done some serious work in the past with web deploy. I've even used Web Deploy to deploy non-web applications, by adding the appropriate targets manually to the project file. I have the MSBUILD book ("Inside the Microsoft® Build Engine: Using MSBuild and Team Foundation Build", by Sayed Ibrahim Hashimi and William Bartholomew), and the Supplement, and know how to do things like add extra files to the MSDEPLOY package which are not in the project, and to add folders, and set access protections, etc.

What I do not know how to do is to make two packages from a single project, and then to deploy the two packages to two separate servers.


Here are two things that I could try. In my (yes, expert) opinion, neither is worth the time. I would be happy to have someone show me where I'm wrong.

A publish profile in Visual Studio not only includes information about which files to publish and to which destination; it also includes which solution configuration to build and deploy. I could either

  1. Have two solution configurations: "Release" and "ReleaseImage". The "Images" project would not build in the "Release" configuration, and the "normal" project would not build in the "ReleaseImage" configuration. The publish profile for the "normal" project would build the "Release" configuration, and the publish profile for the images would build the "ReleaseImage" configuration. I should not have to say how great a pain it would be to have the images, CSS and JavaScript not be in the same project as the code that uses it.
  2. Similar to the first, but keeping everything in a single project. This time, with two configurations, manually edit the .csproj file to place conditionals on the ItemGroup elements containing the content. In effect, the single project would become two projects, depending on the solution configuration. I should not have to state how impractical it would be to have to manually edit the project file every time a new item is added to the project.

I can think of no practical way to do what i need to have done. I was hoping that someone would know of a practical technique that I don't know about - maybe some feature of Web Deploy 3.5 that I was unaware of.

like image 515
John Saunders Avatar asked Jan 10 '14 22:01

John Saunders


1 Answers

This should be as simple as creating two different publish profiles, "PackageApplication" and "PackageContent", both "Web Deploy Package" profiles.

Then it's simply a matter of definiting ExcludeFromPackageFiles items for things you don't want.

PackageApplication.pubxml will look something like this:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>Package</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <DesktopBuildPackageLocation>package\Application.zip</DesktopBuildPackageLocation>
    <PackageAsSingleFile>true</PackageAsSingleFile>
    <DeployIisAppPath />
    <PublishDatabaseSettings>
      <Objects xmlns="" />
    </PublishDatabaseSettings>
  </PropertyGroup>

  <ItemGroup>
    <ExcludeFromPackageFiles Include="**/*.js" />
    <ExcludeFromPackageFiles Include="**/*.css" />
  </ItemGroup>
</Project>

And PackageContent.pubxml will look something like:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>Package</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <DesktopBuildPackageLocation>package\Content.zip</DesktopBuildPackageLocation>
    <PackageAsSingleFile>true</PackageAsSingleFile>
    <DeployIisAppPath />
    <PublishDatabaseSettings>
      <Objects xmlns="" />
    </PublishDatabaseSettings>
  </PropertyGroup>

  <ItemGroup>
    <ExcludeFromPackageFiles Include="**/*.dll;**/*.pdb" />
    <ExcludeFromPackageFiles Include="**/*.cshtml" />
    <ExcludeFromPackageFiles Include="**/*.aspx;**/*.asax" />
    <ExcludeFromPackageFiles Include="**/*.config" />
  </ItemGroup>
</Project>

You'll now have an Application.zip and a Content.zip (complete with .deploy.cmd scripts) that you can deploy to your two web servers.

Caveat I'm not entirely sure if the MSBuild scripts will be smart enough to clear the temporary output directory (out\Debug\Package\PackageTmp) when switching between the profiles, so I'd recommend including /t:Clean;Build in your command line.

like image 96
Richard Szalay Avatar answered Sep 27 '22 22:09

Richard Szalay