在没有虚拟目录设置的CI服务器上使用msdeploy部署包含IIS设置的MVC网站

8
我正在尝试弄清如何使用msdeploy与我的MVC网站一起使用,以便能够自动化部署,包括在远程服务器上设置IIS。
我使用以下命令来创建包:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Clients\PokerLeagueWebSite\PokerLeagueWebSite.csproj /T:Package /p:Configuration=Deployment

我的设置如下:

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

如果我勾选了“包括在IIS中配置的IIS设置”和“包括此Web项目使用的应用程序池设置”,并在开发环境中构建软件包,然后从那里发布,它可以很好地工作。这是我使用的命令:
C:\myproject\Packages\Deployment\PokerLeagueWebSite>PokerLeagueWebSite.deploy.cmd /Y /M:192.168.10.98:8172 /U:administrator /P:password

这会在我的UAT服务器中创建虚拟目录,一切都很好。问题是当我提交到Github并且CI服务器下载和构建它时。自然地,虚拟目录在CI服务器上没有设置,因此构建/打包失败。
我想做的是使用msdeploy提供的打包,并能够远程部署站点和IIS。我想有几个选项:
1)修改MVC项目文件以硬编码iis设置,以便无论何时/在哪里运行构建包,它都会创建具有正确设置的XML文件,因此可以从任何机器部署。我认为这可能可以通过项目根目录中的package.xml文件完成,但我不知道如何设置所有应用程序池和虚拟目录设置。感觉已经完成了一半,但无法完成最后推动。
2)使用PowerShell更改创建的软件包XML文件,以便添加提取IIS设置。
首选第一种选项,因为它将所有信息保存在一个地方,您无需记住在部署之前运行额外的脚本。
我相信我可以使用VS创建软件包并获取所需的设置,然后编写脚本来解决第二个选项,但我对如何完成第一个选项毫无头绪,并花费了相当长时间阅读相关内容,但没有任何成功。

注:

在发布这篇文章之前,我阅读了一些建议的问题,并发现了一些可能性:

MSdeploy使用错误的虚拟目录名称部署MVC 2应用程序

这个问题涉及到在msdeploy命令中传递额外的值,看起来不错,但不是内部构建过程的一部分。不确定要使用哪些命令,但我相信可以通过谷歌搜索找到答案。

这个链接似乎延续了上面的话题:http://msdn.microsoft.com/en-us/library/ee814764.aspx

这个页面讨论了第二个选项的可能性。http://learn.iis.net/page.aspx/1082/web-deploy-parameterization/

我认为这是正确的方法:在网站根目录中使用parameters.xml来处理项目内容: http://vishaljoshi.blogspot.com/2010/07/web-deploy-parameterization-in-action.html 编辑:
我已经继续阅读和测试。使用位于项目根目录的parameters.xml文件,我认为可以实现参数的几乎所有设置。我的问题似乎在于archive.xml文件。这与其他文件非常不同,如果我不勾选“使用IIS设置”复选框,则导致包无法正确安装。我已经开始研究[project].wpp.targets文件,但目前还很困惑。
编辑2:
所以我认为我需要做的是改变[project].sourcemanifest.xml文件的一些设置。我相信这就是驱动archive.xml文件的东西,而现在它有所不同。我认为parameters.xml已经正常工作了。
当不使用IIS时,sourcemanifest.xml如下:
<?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>

但是当我勾选使用IIS设置时,它看起来像这样:

<?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>

我不确定如何更改它,在处理[project].wpp.targets文件,但目前还是摸索中。

编辑3

好的,我曾经以为我已经解决了它。在我的[project].wpp.targets文件中,我有:

<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>

我可以在我的开发机上构建、创建部署包并将其部署到UAT服务器,这很顺利。但是当我在CI服务器上运行它时,它无法构建部署包,在清单阶段出现错误:

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

清单文件看起来像这样:

<?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>

我猜测原因是它仍然有我添加的IisApp和appHostConfig。我只是猜测,还不知道如何删除它。

编辑4

好的,我找到了从清单和参数中删除IISAPP的设置:

<DeployAsIisApp>False</DeployAsIisApp>

这段内容的翻译如下:

这将添加到wpp.targets文件中。

现在出现了一个新问题,它将不再部署。 我认为这与apphostconfig处理站点和iisapp处理虚拟目录有关。

编辑5

所以我一直在比较使用IIS和我的自定义方式之间的差异。

sourcemanifest.xml文件相同 systeminfo.xml文件相同

setparameters.xml:

IIS Web应用程序名称部分不同。在IIS版本中,它具有“默认网站/pokerleague”值,但我的是“C:\websites\pokerleague”。
我认为这就是导致parameters.xml中错误的原因:
IIS Web应用程序具有相同的值,而标签属性具有物理而不是iisapp。

我过去几天一直在尝试完成同样的事情,我会添加更多详细信息,说明为什么这不是立即可能的。在构建期间发生的包创建是一个Manifest => Package同步; 有关该步骤,请参见Microsoft.Web.Publishing.targets的3033行。将您的软件包部署到目标是一个Package(带有内部清单)=>自动同步。appHostConfig提供程序生成具有我们想要参数化的有趣部分的archive.xml文件。不幸的是,它需要引用实际站点以生成所有详细信息,没有注入它们的设施。 - David Peters
1
我一直在开发一个工具来简化这些问题。虽然它还不是100%完美,但可以完成从CI服务器部署网站的工作,而无需任何IIS参与:https://github.com/twistedtwig/AutomdatedDeployments#readme - Jon
2个回答

3

我有类似的工具,可以进行自动化构建和部署:

  • Git仓库
  • VS 2010,ASP.NET MVC 3
  • TeamCity 7.1
  • MSBuild
  • MSDeploy

我将构建、打包和部署步骤分开。我不使用MSDeploy XML文件,而是在命令行上执行相同的操作。

下面是我的步骤:

第一步:编辑Visual Studio项目属性

右键单击“MyAppName”项目->属性,选择“Package/Publish Web”选项卡...

  • 配置:Active(Debug)-这意味着在VS中处于“Debug”配置,并且正在编辑它。“Debug”和“Release”配置都可以选择并独立编辑。
  • Web部署包设置-勾选“创建部署包作为zip文件”。我们需要ZIP文件,以便稍后可以单独部署。
  • IIS网站/应用程序名称-这必须与目标服务器上的IIS网站条目匹配。我使用“MyAppName/”,路径后面没有应用程序名称,因为我手动在IIS中创建了它。这是Web服务器配置的外观。

第一步:手动创建IIS网站(也许你可以自动化,但我不会)。使用MSDeploy时,它会将您的应用程序推送到相匹配的Web Site名称 - 您不必硬编码任何目标文件夹路径或其他内容。

将其与您的项目一起保存,并确保您的更改已检入Git(推送到origin/master)。当CI服务器运行构建步骤时,这些设置将从版本控制中拉取。

第二步:在TeamCity配置中添加一个构建步骤

我编辑构建步骤,并添加了第二个构建步骤,直接使用msbuild构建MyAppName.sln。您可以根据需要进行修改,因为您可能已经以某种方式执行此操作。

第三步:通过安装Microsoft Visual Studio 2010 Shell(集成版)可再发行包来修复构建错误

基本上,我们需要在构建服务器上安装VS,手动复制文件,或安装Microsoft Visual Studio 2010 Shell (Integrated) Redistributable Package

Microsoft.WebApplication.targets未在构建服务器上找到。你的解决方案是什么?

这将使它构建成功,但还没有部署到服务器上。

步骤5:安装MS Web Deployment工具

我获取Web Deployment Tool并进行安装。重新启动后,TeamCity登录出现404错误。原来Web Deploy有一个服务监听端口80,但TeamCity Tomcat服务器也有一个服务监听该端口。短期内,我停止控制面板中的Web Deploy网络服务,并启动TeamCity网络服务。Web Deployment代理服务的目的是接受其他服务器对该服务器的请求。我们不需要这个,因为TeamCity服务器将作为客户端,并将其部署到其他Web服务器上。

网络部署工具也必须安装在目标Web服务器上。我不会在这里过多详述,但您还需要配置服务来监听,以便在运行部署命令时,它会接受并安装在服务器上。对于服务器,我设置了一个名为“webdeploy”的新帐户,并授予其安装权限。
步骤6:创建MSBuild命令以打包Web项目。
我将打包和部署分开成不同的步骤。这将允许构建发布包但手动部署,如果您想要的话。
这是msbuild打包命令:
"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"

让我解释一下命令部分:

MyAppName.csproj:VS项目文件的路径,用于构建。其中有重要选项从项目属性选项卡中设置。

/T:Package:创建一个ZIP包

/P:Configuration=Debug;PackageLocation=***:运行Debug配置。这与在Visual Studio中选择“Debug”设置进行构建是相同的。'Package Location'是它创建的位置。我们稍后将在部署命令中引用软件包文件。

步骤7:创建Web Deploy命令以部署项目##

"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

这个命令也值得详细解释:

-verb:sync : 使网站从源同步到目标

-source:package="C:\Build\MyAppName.Debug.zip" : 源是一个 MSBuild 压缩文件包

-dest:auto,wmsvc=webservername : 使用包文件中的设置部署到服务器。用户帐户是具有权限的操作系统级帐户。指定了主机名,但没有指定 IIS 网站名称(该名称在 MSBuild 项目文件的项目属性中已经指定)。

部署后,我检查了 IIS web 服务器文件,以确保它们具有最新的 DLL 和 web.config 文件。

第8步:从 TeamCity 构建步骤调用 MSDEPLOY

由于现在有两个好的命令(MSBUILD.exe 包装,MSDEPLOY.exe 部署),将它们添加到构建步骤中。我使用命令行运行器,只需像前面两个步骤一样输入相同的命令。

运行所有

当您使用这些步骤运行构建时,如果成功,则可以直接从 git 进行自动部署。

现在,每当新代码合并并推送到 git origin/master 分支时,它都会自动构建和部署到开发服务器。

正如您所看到的,这样就避免了您最初的问题:

问题出在我提交到github后,CI服务器下载并构建它。自然地,在CI服务器上没有设置虚拟目录,因此构建/打包失败。

CI服务器只进行构建和打包。然后将其部署到目标Web服务器。


非常有用。我在长时间的观察中得出了类似的结论和过程。唯一的主要区别是,我现在使用appcmd.exe从开发环境备份iis设置,将其放入源代码控制,并使用此方法(在构建服务器上自动化)将其推送到部署IIS服务器并创建所需的任何网站、应用程序和应用程序池,因此目标机器不必事先了解它。我不希望任何目标机器已经配置好(例如设置农场或云实例等)。 - Jon

1

看一下Appveyor。我们刚刚发布了v2.0,我认为它是WebDeploy的一个非常强大的替代品。整个部署过程可以通过CI服务器上的PowerShell脚本化,并且有PS钩子来自定义该过程。

免责声明:我是Appveyor开发人员。我不是在这里做广告,但如果这对您有用的话,那将是很棒的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接