Skip to content

Instantly share code, notes, and snippets.

@sayedihashimi
Last active March 19, 2022 19:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sayedihashimi/813f42faa0ac4afeb5c617f72aad6909 to your computer and use it in GitHub Desktop.
Save sayedihashimi/813f42faa0ac4afeb5c617f72aad6909 to your computer and use it in GitHub Desktop.
How to publish a web project to multiple IIS sites

Scenario:

  • I have a web project that I want to publish to multiple IIS sites
  • Publish in VS should publish to devs local IIS server (MSDeploy)
  • Publish from CI/CLI should publish to remote env (MSDeploy)
  • CI/CLI and VS publish should be the same
  • Building the solution takes ~3 min and should only be performed once
  • Config files need to be transformed based on the dest env

Question:

How can I accomplish this?

Answer:

There are several different ways that you can solve this issue, each with its own pros/cons. For example, one method would be to create an MSDeploy package, and then use that to publish to multiple locations. In the past I've created package-web which can help with that. But package-web wasn't really designed with this scenario in mind, but more for deployments outside of VS.

I spent some time thinking about this and here is the proposed solution for this problem that I've come up with.

1: Create a script that knows how to publish a folder to an IIS server, with the following characteristics.

  • Parameter for the folder to publish
  • Parameter for env name. Using the env name the script will transform web.original.config using web.ENV.config and place web.config in the publish folder.
  • Parameters needed for publish settings (i.e. MSDeploy settings), or it can be found using conventions and the env name parameter.
  • web.original.config should be excluded from publish using MSDeploy parameters.
  • Parameter for the source folder. This is used for cases outside of VS, and the script should be able to build and publish using a publish profile (more on that below). When this parameter is passed the folder to publish parameter should be ignored.

Note: I personally would create a PowerShell script here

2: Create a publish profile in VS that will do the following.

  • Publish to a folder
  • After publish is finished web.config is renamed to web.original.config. Create a target with AfterTargets="Publish" to do this work.
  • Calls the script created in step 1 to publish to local IIS for the 3 target destinations

Then in VS when a developer publishes the project, it will first publish the files to a folder and run the build config transform (i.e. web.release.config) and then the script is invoked three times to do the local publish.

For your CI/CLI publish you just call the script and pass in different parameters based on the env/dest, as well as the source folder. It should call msbuild.exe to build and publish the project using the folder profile. To do that invoke MSBuild with /p:DeployOnBuild=true;publishprofile="NAME-OF-THIS-PROFILE". Note if you're building a .sln file see my blog post at http://sedodream.com/2013/03/06/HowToPublishOneWebProjectFromASolution.aspx.

As for implementing the script, if you use PowerShell, I'd recommend looking at the publish-module. This is module developed by me and the aspnet team, when I used to work on the team, for ASP.NET 5. It's no longer being used in VS or maintained, but I believe it's high quality and you should be able to fix any issues that you run into. I doubt you'll run into many though. If you do look at that there is good docs using Get-Help. You can also view the help by looking at the .psm1 file on github, for example https://github.com/aspnet/vsweb-publish/blob/master/publish-module.psm1#L264.

With that being said, you don't need to use that module. You can just call msdeploy.exe directly. If you do use PowerShell to do this, and you don't use publish-module then I'd recommend copying the Execute-Command function in that module to your PowerShell file and then use that to invoke msdeploy.exe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment