如何将ASP.NET应用程序部署到活动服务器?


104

我正在寻找用于将ASP.NET Web应用程序项目(不是 ASP.NET网站)部署到生产环境的不同技术/工具?

我对持续集成构建服务器在某个位置放置二进制文件到第一个用户请求击中这些二进制文件之间的工作流特别感兴趣。

  1. 您使用的是某些特定工具还是XCOPY?应用程序如何打包(ZIP,MSI等)?

  2. 首次部署应用程序时,如何设置应用程序池和虚拟目录(是手动创建还是使用某些工具创建)?

  3. 当静态资源发生更改(CSS,JS或图像文件)时,您是重新部署整个应用程序还是仅重新部署已修改的资源?程序集/ ASPX页面更改时如何?

  4. 您是否跟踪给定应用程序的所有已部署版本,并且在出现问题的情况下是否具有将应用程序还原到先前已知的工作状态的过程?

随意完成上一个列表。


这是我们用来部署ASP.NET应用程序的方法:

  1. 我们将Web部署项目添加到解决方案中,并进行设置以构建ASP.NET Web应用程序
  2. 我们将一个安装项目(不是 Web安装项目)添加到解决方案中,并将其设置为采用Web部署项目的输出
  3. 我们添加一个自定义安装操作,并在OnInstall事件中运行一个自定义内部.NET程序集,该程序集使用System.DirectoryServices.DirectoryEntry在IIS中创建应用程序池和虚拟目录(此任务仅在首次部署应用程序时执行) 。我们在IIS中支持多个网站,对虚拟目录进行身份验证并为应用程序池设置身份。
  4. 我们在TFS中添加了自定义任务来构建安装项目(TFS不支持安装项目,因此我们不得不使用devenv.exe来构建MSI)
  5. MSI已安装在实时服务器上(如果有MSI的先前版本,则首先将其卸载)


Visual Studio中的发布向导会将托管服务器上的文件与本地文件进行比较,仅更改需要更改的内容。没有理由无缘无故地推送所有图像。
松饼人

Answers:


25

我们已经使用Setup Factory将所有代码部署在MSI中。如果必须更改,我们将重新部署整个解决方案。对于css文件来说,这听起来有些过分,但它绝对使所有环境保持同步,并且我们确切地知道生产环境(我们以相同的方式部署到所有测试和uat环境)。


19

我们确实将部署滚动到实时服务器,因此我们不使用安装程序项目;我们更像CI:

  • “实时”构建服务器从批准的源(不是仓库的“ HEAD”)构建
  • (备份后;-p)
  • robocopy发布到登台服务器(“实时”,但不在F5群集中)
  • 在登台服务器上完成的最终验证,通常使用“主机”黑客来尽可能地模仿整个事情
  • robocopy / L自动用于在下一个“推送”中分发更改列表,以警告任何错误
  • 作为计划过程的一部分,集群被循环,通过robocopy部署到集群中的节点(当节点不在集群中时)

robocopy自动确保仅部署更改。

重新使用应用程序池等;我喜欢这个实现自动化(见这个问题),但在那一刻它是手动的。不过,我真的想更改它。

(这可能有助于我们拥有自己的数据中心和服务器场“现场”,因此我们不必跨越许多障碍)


你们如何处理approved源代码?分公司?
Shawn Mclean

1
@Shawn我必须强调,这是前一生的工作-很久以前。我什至不记得当时的确切过程。可能基本上是“不要搞砸”。
马克·格雷夫

7

网站

部署者:http : //www.codeproject.com/KB/install/deployer.aspx

我将网站发布到本地文件夹,将其压缩,然后通过FTP上传。然后,服务器上的Deployer提取zip,替换配置值(在Web.Config和其他文件中),仅此而已。

当然,对于首次运行,您需要连接到服务器并设置IIS WebSite,数据库,但是在发布更新之后,这简直是小菜一碟。

数据库

为了使数据库保持同步,我使用http://www.red-gate.com/products/sql-development/sql-compare/

如果服务器在路由器束后面,并且您不能直接连接(这是SQL Compare的要求),请使用https://secure.logmein.com/products/hamachi2/创建VPN。


如果您没有对目标数据库的网络访问权限,则可以要求有访问权的人使用免费工具SQL Snapper拍摄架构快照并将其通过电子邮件发送给您。这样,您可以使用SQL Compare生成同步脚本,然后可以通过电子邮件将其发送回以在远程站点上运行。
David Atkinson

5

我将大多数ASP.NET应用程序部署到Linux服务器,并重新部署所有内容以进行最小的更改。这是我的标准工作流程:

  • 我使用源代码存储库(例如Subversion)
  • 在服务器上,我有一个执行以下操作的bash脚本:
    • 签出最新代码
    • 进行构建(创建DLL)
    • 将文件过滤为基本内容(例如,删除代码文件)
    • 备份数据库
    • 将文件部署到Web服务器中当前日期命名的目录中
    • 如果部署中包含新架构,则更新数据库
    • 将新安装设为默认安装,以便在下次点击时使用

签出是使用Subversion的命令行版本完成的,而构建是使用xbuild(与Mono项目中的msbuild相似)完成的。大多数魔术都是在ReleaseIt中完成的。

在我的开发服务器上,我基本上是持续集成的,但是在生产方面,我实际上是通过SSH进入服务器并通过运行脚本手动启动部署。我的脚本被巧妙地称为“部署”,这就是我在bash提示符下键入的内容。我很有创造力。不。

在生产环境中,我必须输入两次“ deploy”:一次是检出,构建并部署到已过时的目录,一次是将该目录设为默认实例。由于目录已过时,因此只需在相关目录中键入“ deploy”,便可以恢复到以前的任何部署。

初始部署需要花费几分钟,而还原到先前版本则需要花费几秒钟。

对我来说,这是一个不错的解决方案,它仅依赖于三个命令行实用程序(svn,xbuild和releaseit),数据库客户端,SSH和Bash。

我确实需要在CodePlex上更新ReleaseIt的副本:

http://releaseit.codeplex.com/


4

用于ASP.NET的简单XCopy。将其压缩,通过sftp到服务器,解压缩到正确的位置。对于第一次部署,手动设置IIS


4

回答您的问题:

  1. XCopy
  2. 手动地
  3. 对于静态资源,我们仅部署更改的资源。
    对于DLL,我们部署更改后的DLL和ASPX页面。
  4. 是的,是的。

保持它的美观和简单,迄今为止已经为我们节省了很多头痛。


4

您使用的是某些特定工具还是XCOPY?应用程序如何打包(ZIP,MSI等)?

作为BuildMaster的开发人员,这自然是我所使用的。所有应用程序均作为工件构建并打包在工具内,并作为ZIP文件在内部存储。

首次部署应用程序时,如何设置应用程序池和虚拟目录(是手动创建还是使用某些工具创建)?

手动-我们在工具中创建一个更改控件,该控件提醒我们在应用程序通过其测试环境时在将来的环境中执行的确切步骤。也可以使用简单的PowerShell脚本将其自动化,但是我们并不经常添加新的应用程序,因此花一分钟的时间手动创建站点同样容易。

当静态资源发生更改(CSS,JS或图像文件)时,您是重新部署整个应用程序还是仅重新部署已修改的资源?程序集/ ASPX页面更改时如何?

默认情况下,设置工件的过程设置为仅将修改后的文件传输到目标服务器-这包括CSS文件,JavaScript文件,ASPX页面和链接程序集的所有内容。

您是否跟踪给定应用程序的所有已部署版本,并且在出现问题的情况下是否具有将应用程序还原到先前已知的工作状态的过程?

是的,BuildMaster可以为我们处理所有这一切。还原通常与重新执行旧版本升级一样简单,但是有时需要手动还原数据库更改,并且可能会发生数据丢失。基本的回滚过程在此处进行了详细说明:http : //inedo.com/support/tutorials/performing-a-deployment-rollback-with-buildmaster



3

Unfold是我为.net应用程序编写的类似于capistrano的部署解决方案。这是我们在所有项目中使用的,这是一个非常灵活的解决方案。它解决了.net应用程序的大多数典型问题,正如Rob Conery在本博客中所解释的那样。

  • 从某种意义上说,它具有良好的“默认”行为,它可以为您做很多标准的事情:从源代码管理中获取代码,构建,创建应用程序池,设置IIS等
  • 根据源代码控制中的内容发布
  • 它具有任务挂钩,因此可以轻松扩展或更改默认行为
  • 它具有回滚
  • 全部都是powershell,所以没有任何外部依赖
  • 它使用Powershell远程访问远程计算机

这是简介和其他一些博客文章。

因此,要回答上述问题:

  • 应用程序如何打包(ZIP,MSI等)?

    Git(或另一个scm)是在目标计算机上获取应用程序的默认方法。或者,您可以执行本地构建并通过Powereshell远程连接复制结果

  • 首次部署应用程序时,如何设置应用程序池和虚拟目录(是手动创建还是使用某些工具创建)?

    展开使用Powershell的WebAdministration模块配置应用程序池和网站应用程序。它使我们(和您)可以修改应用程序池或网站的任何方面

  • 当静态资源发生更改(CSS,JS或图像文件)时,您是重新部署整个应用程序还是仅重新部署已修改的资源?程序集/ ASPX页面更改时如何?

    是的,这可以展开,任何部署都将与其他部署并排安装。这样,当出现问题时,我们可以轻松回滚。它还使我们能够轻松地将已部署的版本追溯到源代码控制修订版。

  • 您是否跟踪给定应用程序的所有已部署版本?

    是的,展开可以保留旧版本。并非所有版本,而是多个版本。这使得回滚几乎是微不足道的。


很好,但是确实需要从目标计算机访问存储库。
David d C e Freitas 2014年

3

在过去的一年中,我们一直在改进发布流程,现在我们已经对其进行了改进。我正在使用Jenkins来管理我们所有的自动构建和发布,但是我确定您可以使用TeamCity或CruiseControl。

因此,在签入后,我们的“正常”构建会执行以下操作:

  • Jenkins进行了SVN更新以获取最新版本的代码
  • 针对我们自己的本地NuGet存储库运行的NuGet包还原已完成
  • 该应用程序是使用MsBuild编译的。进行此设置是一种冒险,因为您需要在构建框中安装正确的MsBuild,然后安装ASP.NET和MVC dll。(作为一个补充说明,当我<MvcBuildViews>true</MvcBuildViews>输入.csproj文件来编译视图时,msbuild随机崩溃,因此我不得不将其禁用)
  • 编译代码后,就可以运行单元测试了(我正在使用nunit,但是您可以使用任何您想要的东西)
  • 如果所有单元测试均通过,我将停止IIS应用程序池,在本地部署该应用程序(只需几个基本XCOPY命令即可复制必要的文件),然后重新启动IIS(我在IIS锁定文件方面遇到了问题,此问题已解决)它)
  • 对于每种环境,我都有单独的web.config文件。开发人员,开发人员,产品。(我尝试使用Web转换的东西收效甚微)。因此,正确的web.config文件也会在
  • 然后,我使用PhantomJS执行一系列UI测试。它还需要使用不同分辨率(移动设备,台式机)的一堆屏幕截图,并在每个屏幕截图上标记一些信息(页面标题,分辨率)。詹金斯(Jenkins)对处理这些屏幕截图提供了强大的支持,并将它们保存为构建的一部分
  • 集成UI测试通过后,构建即告成功

如果有人单击“部署到UAT”:

  • 如果最后一次构建成功,Jenkins将再次进行SVN更新
  • 使用RELEASE配置编译应用程序
  • 创建“ www”目录,并将应用程序复制到其中
  • 然后,我使用winscp在构建框和UAT之间同步文件系统
  • 我将HTTP请求发送到UAT服务器,并确保返回200
  • 此修订在SVN中标记为UAT-datetime
  • 如果到此为止,构建就成功了!

当我们单击“部署到产品”时:

  • 用户选择先前创建的UAT标签
  • 标签已“切换”到
  • 代码被编译并与Prod服务器同步
  • 对Prod服务器的Http请求
  • 此修订在SVN中标记为Prod-datetime
  • 该版本已压缩并存储

全部完成一个完整的构建过程大约需要30秒,对此我感到非常满意。

该解决方案的优点:

  • 它很快
  • 单元测试应捕获逻辑错误
  • 当UI错误进入生产环境时,屏幕截图有望显示导致该错误的版本号
  • UAT和Prod保持同步
  • Jenkins通过所有提交消息向您展示了UAT和Prod的出色发布历史
  • UAT和Prod版本均被自动标记
  • 您可以看到发布时间以及发布者

该解决方案的主要缺点是:

  • 每当您发布到Prod时,都需要发布到UAT。这是我们做出的明智决定,因为我们一直希望确保UAT与Prod保持最新。不过,这仍然很痛苦。
  • 周围有很多配置文件。我已经尝试在Jenkins中拥有所有功能,但是在此过程中需要一些支持批处理文件。(这些也已签入)。
  • 数据库升级和降级脚本是应用程序的一部分,并在应用程序启动时运行。它有效(大多数情况下),但这很痛苦。

我希望听到其他可能的改进!


2

早在2009年,这个答案就源于此,我们使用CruiseControl.net进行持续集成构建,并输出了Release Media。

从那里开始,我们使用Smart Sync软件与不在负载均衡池中的生产服务器进行比较,然后将更改向上移动。

最后,在验证发行版之后,我们运行了一个DOS脚本,该脚本主要使用RoboCopy将代码同步到实时服务器上,从而在启动或运行时停止/启动IIS。


听起来更像是广告,而不是答案
Alf Moh

1

在我工作的最后一家公司,我们曾经使用rSync批处理文件进行部署,仅上传自上次上传以来的更改。rSync的优点在于,您可以添加排除列表以排除特定的文件或文件名模式。因此,例如,排除我们所有的.cs文件,解决方案和项目文件确实非常容易。

我们使用TortoiseSVN进行版本控制,因此很高兴能够编写一些SVN命令来完成以下任务:

  • 首先,请检查用户是否具有最新版本。如果不是,请提示他们进行更新或在该处运行更新。
  • 从服务器上下载一个名为“ synclog.txt”的文本文件,其中详细说明了SVN用户的身份,他们正在上传的修订版本号以及上传的日期和时间。为当前上传内容添加新行,然后将其与更改的文件一起发送回服务器。这样一来,就可以很轻松地找到要回滚到哪个版本的网站,以免上载会导致问题。

除此之外,还有第二个批处理文件,它仅检查实时服务器上的文件差异。这可以突出显示一个常见问题,即有人会上传但不将其更改提交到SVN。结合上面提到的同步日志,我们可以找出谁可能是罪魁祸首,并要求他们进行工作。

最后,rSync允许您备份在上载期间替换的文件。我们已经将它们移动到备份文件夹中,因此,如果您突然意识到某些文件不应该被覆盖,则可以找到该文件夹​​中每个文件的最新备份版本。

尽管当时的解决方案有点笨拙,但在那种上传方法不太优雅或不那么方便的环境(例如,远程桌面,复制并粘贴整个网站)的环境中工作时,我对此变得更加欣赏。 。


1

我建议不仅覆盖现有的应用程序文件,而且建议为每个版本创建一个目录,并将IIS应用程序重新指向新路径。这有几个好处:

  • 如有需要,可快速还原
  • 无需停止IIS或应用程序池即可避免锁定问题
  • 没有旧文件引起问题的风险
  • 或多或少的零停机时间(通常只是在新的Appdomain初始化时暂停)

我们遇到的唯一问题是,如果您不重新启动应用程序池并依靠自动的appdomain开关,则资源将被缓存。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.