Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

deploy MVC site with msdeploy including IIS settings from CI server that doesn't have virtual directory setup

I am trying to figure out how to use msdeploy with my MVC site to be able to automate the deployments including setting up IIS on the remote server.

I use the following command to create the package:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Clients\PokerLeagueWebSite\PokerLeagueWebSite.csproj /T:Package /p:Configuration=Deployment

My setup is as follows:

local dev box using VS2010 + GIT
GITHUB for repo
Teamcity for CI server (different machine to dev box)
remote (same network) UAT server

If I tick the "Include IIS Settings as configured in IIS" and "Include application pool settings used by this web project" and build the package on my dev box then publish from there it works great. Here is the command I use:

C:\myproject\Packages\Deployment\PokerLeagueWebSite>PokerLeagueWebSite.deploy.cmd /Y /M:192.168.10.98:8172 /U:administrator /P:password

This creates the virtual directory within my UAT server and all is well. The problem is when I commit to github and the CI server downloads and builds it. Naturally the virtual directory is not setup on the CI server so the build / package fails.

What I want to do is use the packaging that msdeploy gives and be able to deploy the site and IIS remotely. I guess there are a few options:

1) Alter the MVC project file to hard code iis settings so that when ever / where ever you run the build package it creates the XML files with the correct settings so it can be deployed from any machine. I think this might be able to be done with the package.xml file in the root of the project, but I have no idea how I setup all the app pool and virtual directory settings. Feel like I am half way there but can't get the final push across the line.

2) Use powershell to alter created package XML files so that the extract IIS settings are added.

The first option is preferable as it keeps all the information in one place and you don't need to remember to run an extra script before deployments.

I believe I could figure the second option out by using VS to create the package and get the settings I need then script it, but I don't have a clue and spent a fair while reading about it without any success on how I would do option one.

N.B.

Reading some of the suggested questions before I posted this I can see some sort of possibilities:

MSdeploy deploys an MVC 2 application with wrong virtual directory name

This question talks about passing extra values on the msdeploy command, seems OK but not internal to the build process so to speak. Not sure of all the commands to use but can google that I am sure.

This links seems to continue with the above: http://msdn.microsoft.com/en-us/library/ee814764.aspx

This page takes about the possibilities for option 2. http://learn.iis.net/page.aspx/1082/web-deploy-parameterization/

Think this is the way: using parameters.xml in teh root of the site for project stuff: http://vishaljoshi.blogspot.com/2010/07/web-deploy-parameterization-in-action.html

EDIT

I have continued reading and testing around this. Using the parameters.xml file in the root of the project I can get the parameters pretty much there I think. My issue seems to be the archive.xml file. This is pretty different and is what is causing the package to not install correctly if I do not have the use IIS settings check box ticked. I have started to read about [project].wpp.targets file that might help but pretty darn lost with that atm.

EDIT 2

So what I think I need to do is get the [project].sourcemanifest.xml file to change a few of its settings. I believe this is what drives the archive.xml which is what is different now. I have the parameters.xml working correctly I think.

When NOT using IIS the sourcemanifest.xml looks like this:

<?xml version="1.0" encoding="utf-8"?>
<sitemanifest>
  <IisApp path="C:\hoh_code\GIT\ai-poker-project\Clients\PokerLeagueWebSite\obj\Deployment\Package\PackageTmp" managedRuntimeVersion="v4.0" />
  <setAcl path="C:\hoh_code\GIT\ai-poker-project\Clients\PokerLeagueWebSite\obj\Deployment\Package\PackageTmp" setAclResourceType="Directory" />
  <setAcl path="C:\hoh_code\GIT\ai-poker-    project\Clients\PokerLeagueWebSite\obj\Deployment\Package\PackageTmp"     setAclUser="anonymousAuthenticationUser" setAclResourceType="Directory" />
</sitemanifest>

But when I tick the use IIS settings it looks like this:

<?xml version="1.0" encoding="utf-8"?>
<sitemanifest>
  <appHostConfig path="Default Web Site/PokerLeague" />
  <contentPath path="C:\hoh_code\GIT\ai-poker-project\Clients\PokerLeagueWebSite\obj\Deployment\Package\PackageTmp" />
  <setAcl path="C:\hoh_code\GIT\ai-poker-project\Clients\PokerLeagueWebSite\obj\Deployment\Package\PackageTmp" setAclResourceType="Directory" />
  <setAcl path="C:\hoh_code\GIT\ai-poker-project\Clients\PokerLeagueWebSite\obj\Deployment\Package\PackageTmp" setAclUser="anonymousAuthenticationUser" setAclResourceType="Directory" />
</sitemanifest>

Not sure how to change it, working on the [project].wpp.targets file, but fumbling in the dark atm.

EDIT 3

OK so I thought I had it for a minute. in my [project].wpp.targets file I have:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>

    <AddContentPathToSourceManifestDependsOn>
      SetCustomACLs;
    </AddContentPathToSourceManifestDependsOn >
  </PropertyGroup>

  <Target Name="SetCustomACLs">
    <ItemGroup>
      <MsDeploySourceManifest Include="appHostConfig">
        <Path>Default Web Site/PokerLeague</Path>
      </MsDeploySourceManifest>
    </ItemGroup>
    <ItemGroup>
        <MsDeploySourceManifest Include="contentPath">
            <Path>$(_MSDeployDirPath_FullPath)</Path>
        </MsDeploySourceManifest>
    </ItemGroup>
  </Target>
</Project>

Which builds, creates a deployment package that I can then deploy from my dev box to the UAT server and it works. But when I run it on my CI server it will not build the deployment package, it drops out at the manifest stage with the error:

One or more entries in the manifest 'sitemanifest' are not valid. 

The manifest file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<sitemanifest>
  <appHostConfig path="Default Web Site/PokerLeague" />
  <contentPath path="C:\TeamCity\buildAgent\work\71e78d4c543e0594\Clients\PokerLeagueWebSite\obj\Deployment\Package\PackageTmp" />
  <IisApp path="C:\TeamCity\buildAgent\work\71e78d4c543e0594\Clients\PokerLeagueWebSite\obj\Deployment\Package\PackageTmp" managedRuntimeVersion="v4.0" />
  <setAcl path="C:\TeamCity\buildAgent\work\71e78d4c543e0594\Clients\PokerLeagueWebSite\obj\Deployment\Package\PackageTmp" setAclResourceType="Directory" />
  <setAcl path="C:\TeamCity\buildAgent\work\71e78d4c543e0594\Clients\PokerLeagueWebSite\obj\Deployment\Package\PackageTmp" setAclUser="anonymousAuthenticationUser" setAclResourceType="Directory" />
</sitemanifest>

I am guessing it is because it still has the IisApp as well as the appHostConfig that I added. I am just guessing about this, and don't know how to remove that yet.

EDIT 4

OK so I found the setting to remove the IISAPP from the manifest and parameters:

<DeployAsIisApp>False</DeployAsIisApp>

This goes into the wpp.targets file.

This has now created a new issue that it will no longer deploy. I believe this is something to do with apphostconfig dealing with sites and iisapp dealing with virtual directories.

EDIT 5

so I have been going through the differences left between ticking with IIS and my custom one.

sourcemanifest.xml files are the same systeminfo.xml are the same

setparameters.xml:

The IIS web applicaiton name section is different. With IIS version is has the "Default Web Site/pokerleague" value but mine has "C:\websites\pokerleague".

I think this is what is driving the error in the parameters.xml:

the IIS web application has those same values and the tags attribute has physical rather than iisapp.

like image 716
Jon Avatar asked Feb 20 '12 07:02

Jon


People also ask

Where is MSDeploy exe located?

MSDeploy.exe can be usually found under path C:\Program Files\IIS\Microsoft Web Deploy V3 on your computer.


1 Answers

I have similar tools, and do automated build and deployment:

  • git repo
  • vs 2010 , asp.net mvc 3
  • teamcity 7.1
  • msbuild
  • msdeploy

I separate the build, packaging, and deployment steps. I don't use the msdeploy xml files, but do the same thing on the command line.

These are my steps:

Step 1: edit the Visual Studio project properties

right-click "MyAppName" project -> Properties... , tab "Package/Publish Web" ...

  • Configuration: Active (Debug) - this means the 'Debug' config is active in VS, and you are editing it. The 'Debug' and 'Release' configurations both can be selected and independently edited.
  • Web Deployment Package Settings - check "Create deployment package as zip file". We want the ZIP file so it can be deployed separately later.
  • IIS Web Site/application name - This must match the IIS Web site entry on the target server. I use "MyAppName/" with no app name after the path, because i create that in IIS manually. That is how it looks on the web server config.

I create the IIS web site manually the first time (maybe you can automate, i don't). When using MSDeploy, it will push your app to the matching Web Site name - you don't have to hardcode any destination folder paths or anything.

Save it with your project, and make sure your changes are checked into Git (pushed to origin/master). Those settings will be pulled from version control when the CI server runs the build steps.

Step 2: add a Build Step in the TeamCity config

I edit the Build Steps, and add a second build step, to build the MyAppName.sln directly, using msbuild. You can modify as you like, as you probably already do this some way.

Step 3: fix build error by installing Microsoft Visual Studio 2010 Shell (Integrated) Redistributable Package

Basically, either we need to install VS on the build server, manually copy files, or install the Microsoft Visual Studio 2010 Shell (Integrated) Redistributable Package.

Microsoft.WebApplication.targets was not found, on the build server. What's your solution?

This will get it to build. Still no deployment to a server yet.

Step 5: Install the MS Web Deployment tool

I get the Web Deployment Tool here and install. After reboot, the TeamCity login has a 404 error. Turns out Web Deploy has a service which listens on port 80, but so does TeamCity Tomcat server. For short term, i stop the Web Deploy web service in control panel, and start the TeamCity web service. The purpose of the Web Deployment Agent Service is to accept requests to that server from other servers. We don't need that, because the TeamCity server will act as a client, and deploy out to other web servers.

The Web Deployment Tool also has to be installed on the target web server. I'm not going to go too far into detail here, but you have to configure the service to listen as well, so when you run the deployment command, it accepts it and installs on the server. For the server, i set up a new account named 'webdeploy' with permission to install.

Step 6: Create a MSBuild command to package the Web project

I do separate steps for packaging and deployment. This will allow cases for building a Release package but manually deploying it, if you want.

This is the msbuild package command:

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" 
           MyAppName/MyAppName/MyAppName.csproj 
           /T:Package 
           /P:Configuration=Debug;PackageLocation="C:\Build\MyAppName.Debug.zip"

Let me explain the command parts:

MyAppName.csproj : path to VS project file to build. There are important options in there which get set from the project Properties tabs.

/T:Package : create a ZIP package

/P:Configuration=Debug;PackageLocation=*** : run the Debug configuration. This is the same as Build in Visual Studio with the 'Debug' setting selected. The 'Package Location' is what it created. We will reference the package file later in the deployment command.

Step 7: Create a Web Deploy command to deploy the project ##

"C:\Program Files\IIS\Microsoft Web Deploy V2\msdeploy.exe" -verb:sync 
     -source:package="C:\Build\MyAppName.Debug.zip" 
     -dest:auto,wmsvc=webservername,username=webdeploy,password=******* 
     -allowUntrusted=true

This command is also worth explaining in detail:

-verb:sync : makes the web site sync from the source to the destination

-source:package="C:\Build\MyAppName.Debug.zip" : source is an MSBuild zip file package

-dest:auto,wmsvc=webservername : use the settings in the package file to deploy to the server. The user account is an OS-level account with permission. The hostname is specified, but not the IIS web site name (which is previously specified in the MSBuild project file in the project properties).

After deployment, i checked the IIS web server files, to make sure they had the latest DLLs and web.config file.

Step 8: Call the MSDEPLOY from the TeamCity build steps

Since there are now have 2 good commands (MSBUILD.exe to package, MSDEPLOY.exe to deploy), add them to the build steps. I use the command line runner, and just put in the same command as the prior 2 steps.

run it all

When you run the build with these steps, if they succeed, you have automatic deployment directly from git.

Now every time new code gets merged and pushed to git origin/master branch, it will automatically build and deploy the the development server.

As you can see, this avoids your original problem:

The problem is when I commit to github and the CI server downloads and builds it. Naturally the virtual directory is not setup on the CI server so the build / package fails.

The CI server only builds and packages. Then it deploys to the target web server.

like image 84
Raul Nohea Goodness Avatar answered Oct 08 '22 20:10

Raul Nohea Goodness