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

时间:2009-07-17 13:30:13

标签: asp.net deployment

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

我对持续集成构建服务器在某个位置删除二进制文件的时间与第一个用户请求命中这些二进制文件的时间之间发生的工作流程特别感兴趣。

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

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

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

  4. 您是否跟踪给定应用程序的所有已部署版本?如果出现问题,您是否有将应用程序恢复到之前已知工作状态的过程?

  5. 随意填写上一个清单。


    以下是我们用于部署ASP.NET应用程序的内容:

    1. 我们在解决方案中添加Web Deployment Project并将其设置为构建ASP.NET Web应用程序
    2. 我们向解决方案添加一个安装项目( NOT Web安装项目),并将其设置为获取Web部署项目的输出
    3. 我们添加自定义安装操作,在OnInstall事件中,我们运行自定义生成.NET程序集,使用System.DirectoryServices.DirectoryEntry在IIS中创建应用程序池和虚拟目录(此任务仅在应用程序第一次执行时执行被部署)。我们支持IIS中的多个网站,虚拟目录的身份验证以及为应用程序池设置身份。
    4. 我们在TFS中添加一个自定义任务来构建安装项目(TFS不支持安装项目,所以我们必须使用devenv.exe来构建MSI)
    5. MSI安装在实时服务器上(如果首次卸载MSI的先前版本)

12 个答案:

答案 0 :(得分:24)

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

答案 1 :(得分:19)

我们对实时服务器进行滚动部署,因此我们不使用安装程序项目;我们有更像CI的东西:

  • “实时”构建服务器构建来自已批准来源(不是回购的“HEAD”)
  • (在备份之后;-p)
  • robocopy发布到临时服务器(“实时”,但不在F5群集中)
  • 在登台服务器上完成最终验证,通常使用“主机”黑客来尽可能地模拟整个事物
  • robocopy / L会自动用于在下一次“推送”中分发更改列表,以提醒任何蠢事
  • 作为计划流程的一部分,群集将循环,通过robocopy部署到群集中的节点(当它们不在群集中时)

robocopy会自动确保只部署更改。

重新使用App Pool等;我会喜欢这是自动化的(see this question),但在时刻它是手动的。不过,我真的想改变它。

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

答案 2 :(得分:7)

网站

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

我将网站发布到本地文件夹,压缩,然后通过FTP上传。服务器上的部署者然后提取zip,替换配置值(在Web.Config和其他文件中),就是这样。

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

数据库

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

如果服务器落后于一堆路由器并且您无法直接连接(这是SQL Compare的要求),请使用https://secure.logmein.com/products/hamachi2/创建VPN。

答案 3 :(得分:5)

我主要将ASP.NET应用程序部署到Linux服务器,并重新部署所有内容,即使是最小的更改。这是我的标准工作流程:

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

使用命令行版本的Subversion完成Checkout,并使用xbuild完成构建(msbuild与Mono项目类似)。大多数魔法都是在ReleaseIt中完成的。

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

在生产中,我必须两次输入'deploy':一次签出,构建和部署到一个过时的目录,一次将该目录作为默认实例。由于目录已过时,我只需在相关目录中输入“deploy”即可恢复到以前的任何部署。

初始部署需要几分钟时间,并且恢复到先前版本需要几秒钟。

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

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

http://releaseit.codeplex.com/

答案 4 :(得分:4)

ASP.NET的简单XCopy。拉上它,sftp到服务器,提取到正确的位置。对于第一次部署,手动设置IIS

答案 5 :(得分:4)

回答你的问题:

  1. 的XCopy
  2. 手动
  3. 对于静态资源,我们只部署已更改的资源  对于DLL,我们部署了更改的DLL和ASPX页面。
  4. 是的,是的。
  5. 保持美好而简单至今为我们带来了很多麻烦。

答案 6 :(得分:4)

  

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

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

  

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

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

  

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

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

  

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

是的,BuildMaster为我们处理所有这些。恢复大多与重新执行旧的构建升级一样简单,但有时需要手动恢复数据库更改,并且可能发生数据丢失。基本回滚过程详见:http://inedo.com/support/tutorials/performing-a-deployment-rollback-with-buildmaster

答案 7 :(得分:3)

网络设置/安装项目 - 如果出现问题,您可以轻松卸载

答案 8 :(得分:3)

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

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

这是introduction和其他一些博文。

所以回答上面的问题:

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

    Git(或其他scm)是在目标计算机上获取应用程序的默认方式。或者,您可以执行本地构建并通过Powereshell远程连接

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

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

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

    是展开这样做,任何部署都安装在其他部署旁边。这样我们就可以轻松回滚 什么时候出错了。它还允许我们轻松追溯已部署的版本 源代码控制修订版。

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

    是的,展开会保留旧版本。不是所有版本,而是许多版本。它使回滚几乎无足轻重。

答案 9 :(得分:3)

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

因此,在签到时,我们的#34;正常" build执行以下操作:

  • Jenkins进行SVN更新以获取最新版本的代码
  • NuGet包恢复已针对我们自己的本地NuGet存储库运行
  • 使用MsBuild编译应用程序。设置它是一个冒险,因为你需要在你的构建盒上安装正确的MsBuild然后安装ASP.NET和MVC dll。 (作为旁注,当我在我的.csproj文件中输入<MvcBuildViews>true</MvcBuildViews>来编译视图时,msbuild随机崩溃,所以我不得不禁用它)
  • 编译代码后,运行单元测试(我为此使用nunit,但你可以使用你想要的任何东西)。
  • 如果所有单元测试都通过,我会停止IIS应用程序池,在本地部署应用程序(只需几个基本的XCOPY命令来复制必要的文件),然后重新启动IIS(我已经遇到IIS锁定问题文件,这解决了它)
  • 我为每个环境都有单独的web.config文件; dev,uat,prod。 (我尝试使用网络转换的东西,但收效甚微)。因此,正确的web.config文件也会在
  • 中复制
  • 然后我使用PhantomJS执行一系列UI测试。它还需要在不同分辨率(移动设备,桌面设备)上截取一组屏幕截图,并在每个屏幕截图上标记一些信息(页面标题,分辨率)。 Jenkins非常支持处理这些屏幕截图,并将它们保存为构建
  • 的一部分
  • 集成UI测试通过后,构建成功

如果有人点击&#34;部署到UAT&#34;:

  • 如果上次构建成功,Jenkins会再次进行SVN更新
  • 使用RELEASE配置编译应用程序
  • A&#34; www&#34;创建目录并将应用程序复制到其中
  • 然后我使用winscp来同步构建框和UAT之间的文件系统
  • 我向UAT服务器发送HTTP请求,并确保收到200
  • 此版本在SVN中标记为UAT-datetime
  • 如果我们已经做到这一点,那么构建是成功的!

点击&#34; Deploy to Prod&#34;:

  • 用户选择之前创建的UAT标记
  • 标签是&#34;切换&#34;到
  • 编译代码并与Prod服务器同步
  • 向Prod服务器发送Http请求
  • 此版本在SVN中标记为Prod-datetime
  • 该版本已压缩并存储

所有完整的制作到制作需要大约30秒,我非常非常满意。

此解决方案的好处:

  • 快速
  • 单元测试应该捕获逻辑错误
  • 当UI错误投入生产时,屏幕截图有望显示#导致它的修订
  • UAT和Prod保持同步
  • Jenkins向UAT和Prod展示了一个很棒的发布历史记录,其中包含所有提交消息
  • UAT和Prod版本都已自动标记
  • 你可以看到发布的时间和发生的时间

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

  • 每当你向Prod发布一个版本时,你需要向UAT发布一个版本。这是我们做出的有意识的决定,因为我们希望始终确保UAT始终与Prod保持同步。不过,这很痛苦。
  • 周围有很多配置文件。我试图在Jenkins中完成所有工作,但是在此过程中需要一些支持批处理文件。 (这些也已签入)。
  • 数据库升级和降级脚本是应用程序的一部分,在应用启动时运行。它(主要)起作用,但它很痛苦。

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

答案 10 :(得分:2)

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

从那里我们使用Smart Sync software来比较负载平衡池之外的生产服务器,并将更改移出。

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

答案 11 :(得分:1)

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

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

  • 首先,检查用户是否有最新版本。如果没有,请提示他们更新或立即运行更新。
  • 从名为“synclog.txt”的服务器下载文本文件,详细说明SVN用户是谁,他们上传的修订版号以及上传的日期和时间。为当前上载附加一个新行,然后将其与更改的文件一起发送回服务器。这样可以非常轻松地找到要回滚的网站版本,以免上传导致问题。

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

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

虽然当我在上传方法不那么优雅或简单(远程桌面,复制和粘贴整个网站)的环境中工作时,我的解决方案感觉有点笨拙,但后来我更加欣赏它了。例如)。