我正在寻找用于将ASP.NET Web应用程序项目( NOT ASP.NET网站)部署到 生产环境 中的不同技术/工具?
我对持续集成构建服务器在某个位置删除二进制文件的时间与第一个用户请求命中这些二进制文件的时间之间发生的工作流程特别感兴趣 .
-
您使用的是某些特定工具还是只使用XCOPY?如何打包应用程序(ZIP,MSI,...)?
-
首次部署应用程序时,如何设置应用程序池和虚拟目录(是手动创建还是使用某些工具创建)?
-
当静态资源发生变化(CSS,JS或图像文件)时,您是重新部署整个应用程序还是仅重新部署修改后的资源?汇编/ ASPX页面何时更改?
-
您是否跟踪给定应用程序的所有已部署版本?如果出现问题,您是否有将应用程序还原到先前已知工作状态的过程?
随意完成以前的列表 .
以下是我们用于部署ASP.NET应用程序的内容:
-
我们在解决方案中添加Web Deployment Project并将其设置为构建ASP.NET Web应用程序
-
我们向解决方案添加了一个安装项目( NOT Web安装项目)并将其设置为获取Web部署项目的输出
-
我们添加自定义安装操作,在OnInstall事件中,我们运行自定义生成.NET程序集,使用System.DirectoryServices.DirectoryEntry在IIS中创建应用程序池和虚拟目录(此任务仅在第一次部署应用程序时执行) . 我们支持IIS中的多个网站,虚拟目录的身份验证以及为应用程序池设置身份 .
-
我们在TFS中添加了一个自定义任务来构建安装项目(TFS不支持安装项目,因此我们必须使用devenv.exe来构建MSI)
-
MSI安装在实时服务器上(如果首先卸载了MSI的先前版本)
13 回答
我们使用Setup Factory在MSI中部署了所有代码 . 如果必须改变某些事情,我们会重新部署整个解决方案 . 这对于css文件来说听起来有点过分,但它绝对可以让所有环境保持同步,并且我们确切知道 生产环境 中的内容(我们以相同的方式部署到所有测试和uat环境) .
我们对实时服务器进行滚动部署,因此我们不使用安装程序项目;我们有更像CI的东西:
"live"构建服务器从 approved 源构建(不是repo的"HEAD")
(在备份之后;-p)
robocopy发布到登台服务器("live",但不在F5集群中)
__9__在登台服务器上完成最终验证,通常使用"hosts" hacks尽可能地模拟整个事物
robocopy / L会自动用于分发下一个"push"中的更改列表,以提醒任何傻瓜
作为计划进程的一部分,循环群集,通过robocopy部署到群集中的节点(当它们不在群集中时)
robocopy会自动确保仅部署更改 .
重新申请App Pool等;我想 love 这是自动化的(see this question),但目前它是手动的 . 不过,我真的想改变它 .
(这可能有助于我们拥有自己的数据中心和服务器场“现场”,因此我们不必跨越许多障碍)
Website
部署人员:http://www.codeproject.com/KB/install/deployer.aspx
我将网站发布到本地文件夹,压缩它,然后通过FTP上传 . 服务器上的部署者然后提取zip,替换配置值(在Web.Config和其他文件中),就是这样 .
当然,对于第一次运行,您需要连接到服务器并设置IIS WebSite,数据库,但之后发布更新是小菜一碟 .
Database
为了保持数据库同步,我使用http://www.red-gate.com/products/sql-development/sql-compare/
如果服务器落后于一堆路由器并且您无法直接连接(这是SQL Compare的要求),请使用https://secure.logmein.com/products/hamachi2/创建VPN .
我主要将ASP.NET应用程序部署到Linux服务器,并重新部署所有内容,即使是最小的更改 . 这是我的标准工作流程:
我使用的是源代码库(比如Subversion)
在服务器上,我有一个执行以下操作的bash脚本:
查看最新代码
是否构建(创建DLL)
将文件过滤到基本要素(例如删除代码文件)
备份数据库
将文件部署到以当前日期命名的目录中的Web服务器
如果部署中包含新架构,则更新数据库
使新安装成为默认设置,以便在下次命中时提供
Checkout是使用Subversion的命令行版本完成的,并且使用xbuild完成构建(msbuild类似于Mono项目) . 大多数魔法都是在ReleaseIt中完成的 .
在我的开发服务器上,我基本上有持续集成,但在 生产环境 方面,我实际上是SSH到服务器并通过运行脚本手动启动部署 . 我的脚本被巧妙地称为“部署”,这就是我在bash提示符下键入的内容 . 我很有创意 . 不 .
在 生产环境 中,我必须两次输入'deploy':一次签出,构建和部署到一个过时的目录,一次将该目录作为默认实例 . 由于目录已过时,我只需在相关目录中键入“deploy”即可恢复到以前的任何部署 .
初始部署需要几分钟,并且恢复到先前版本需要几秒钟 .
它对我来说是一个很好的解决方案,仅依赖于三个命令行实用程序(svn,xbuild和releaseit),数据库客户端,SSH和Bash .
我真的需要在CodePlex上更新ReleaseIt的副本:
http://releaseit.codeplex.com/
适用于ASP.NET的简单XCopy . 拉上它,sftp到服务器,提取到正确的位置 . 对于第一次部署,手动设置IIS
回答你的问题:
XCopy
手动
对于静态资源,我们仅部署已更改的资源 .
对于DLL,我们部署更改的DLL和ASPX页面 .
是的,是的 .
保持它的美观和简单至今为我们带来了许多令人头疼的问题 .
作为BuildMaster的开发人员,这自然是我使用的 . 所有应用程序都在工具中构建和打包为工件,这些工件在内部存储为ZIP文件 .
手动 - 我们在工具中创建一个更改控件,提醒我们在应用程序在其测试环境中移动时在未来环境中执行的确切步骤 . 这也可以通过简单的PowerShell脚本实现自动化,但我们不会经常添加新的应用程序,因此花费1分钟手动创建站点也同样容易 .
默认情况下,设置部署工件的过程,以便只将已修改的文件传输到目标服务器 - 这包括CSS文件,JavaScript文件,ASPX页面和链接的程序集中的所有内容 .
是的,BuildMaster为我们处理所有这些 . 恢复主要与重新执行旧的构建升级一样简单,但有时需要手动恢复数据库更改,并且可能会发生数据丢失 . 基本回滚过程详见:http://inedo.com/support/tutorials/performing-a-deployment-rollback-with-buildmaster
Web设置/安装项目 - 如果出现问题,您可以轻松卸载它
Unfold 是我为.net应用程序编写的类似capistrano的部署解决方案 . 这是我们在所有项目中使用的,它是一个非常灵活的解决方案 . 它解决了.net应用程序的大多数典型问题,如Rob Conery在this blog post中所解释的那样 .
它有一个很好的"default"行为,因为它为你做了很多标准的东西:从源代码控制获取代码,构建,创建应用程序池,设置IIS等
根据 source control 中的内容
发布
它有 task hooks ,因此可以轻松扩展或更改默认行为
它有 rollback
这都是 powershell ,因此没有任何外部依赖项
它使用powershell远程访问来访问远程机器
这是一篇introduction和其他一些博客文章 .
所以回答上面的问题:
Git(或其他scm)是在目标计算机上获取应用程序的默认方式 . 或者,您可以执行本地构建并通过Powereshell远程连接复制结果
Unfold使用Powershell的Web管理模块配置应用程序池和网站应用程序 . 它允许我们(和您)修改应用程序池或网站的任何方面
是展开这样做,任何部署都安装在其他部署旁边 . 这样我们就可以在出现问题时轻松回滚 . 它还允许我们轻松地将已部署的版本追溯到源控件修订版 .
是的,展开旧版本 . 不是所有版本,而是许多版本 . 它几乎回滚不重要的 .
在过去的一年里,我们一直在改进我们的发布流程,现在我们已经完成了它 . 我正在使用Jenkins管理所有自动构建和发布,但我确信您可以使用TeamCity或CruiseControl .
因此,在签入时,我们的“正常”构建执行以下操作:
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测试 . 它还需要在不同分辨率(移动设备,桌面设备)上截取一组屏幕截图,并在每个屏幕截图上标记一些信息(页面 Headers ,分辨率) . Jenkins非常支持处理这些屏幕截图,并将它们保存为构建的一部分
集成UI测试通过后,构建成功
如果有人点击“部署到UAT”:
如果最后一次构建成功,Jenkins会再次进行SVN更新
使用RELEASE配置编译应用程序
创建"www"目录并将应用程序复制到其中
然后我使用winscp来同步构建框和UAT之间的文件系统
我向UAT服务器发送HTTP请求,并确保返回200
此版本在SVN中标记为UAT-datetime
如果我们到目前为止,构建成功!
当我们点击“Deploy to Prod”时:
用户选择先前创建的UAT标记
标签是"switched" to
编译代码并与Prod服务器同步
向Prod服务器发送Http请求
此版本在SVN中标记为Prod-datetime
该版本已压缩并存储
所有完整的制作到制作需要大约30秒,我非常非常满意 .
该解决方案的优势:
这很快
单元测试应该捕获逻辑错误
当UI错误投入 生产环境 时,屏幕截图将有希望显示#引起它的修订版
UAT和Prod保持同步
Jenkins向UAT和Prod展示了一个很棒的发布历史记录,其中包含所有提交消息
UAT和Prod版本都会自动标记
您可以看到发布的时间以及发生的时间
该解决方案的主要缺点是:
每当你向Prod发布一个版本时,你需要向UAT发布一个版本 . 这是我们做出的有意识的决定,因为我们希望始终确保UAT始终与Prod保持同步 . 不过,这很痛苦 .
有's quite a few configuration files floating around. I'试图在Jenkins中完成所有操作,但在此过程中需要一些支持批处理文件 . (这些也是签入的) .
数据库升级和降级脚本是应用程序的一部分,在应用启动时运行 . 它(主要)起作用,但这很痛苦 .
我很想听到任何其他可能的改进!
早在2009年,这个答案来自于,我们使用CruiseControl.net进行持续集成构建,同时还输出了Release Media .
从那里我们使用Smart Sync software来比较负载 balancer 池之外的 生产环境 服务器,并将更改向上移动 .
最后,在验证发布后,我们运行了一个DOS脚本,主要使用RoboCopy将代码同步到实时服务器,停止/启动IIS .
在我工作的最后一家公司,我们过去使用rSync批处理文件进行部署,仅上传自上次上传以来的更改 . rSync的优点在于您可以添加排除列表以排除特定文件或文件名模式 . 因此,排除所有.cs文件,解决方案和项目文件非常简单 .
我们使用TortoiseSVN进行版本控制,因此很高兴能够编写几个SVN命令来完成以下任务:
首先,检查用户是否有最新版本 . 如果没有,请提示他们更新或在那里运行更新 .
从名为"synclog.txt"的服务器下载文本文件,其中详细说明了SVN用户的身份,他们上传的修订版号以及上传的日期和时间 . 为当前上载附加一个新行,然后将其与更改后的内容一起发送回服务器文件 . 这使得很容易找到哪个版本的网站可以回滚到上传导致问题的可能性 .
除此之外,还有第二个批处理文件,它只检查实时服务器上的文件差异 . 这可以突出显示有人上传但未将其更改提交到SVN的常见问题 . 结合上面提到的同步日志,我们可以找出可能的罪魁祸首是谁,并要求他们投入工作 .
最后,rSync允许您备份上载期间替换的文件 . 我们将它们移动到备份文件夹中如果你突然意识到某些文件不应该被覆盖,你可以找到该文件夹中每个文件的最后一个备份版本 .
虽然当我在上传方法不那么优雅或容易的环境中工作时(例如,远程桌面,复制并粘贴整个站点),我在此之后感觉有点笨拙,但后来我更加欣赏它了 . .
我建议不要只覆盖现有的应用程序文件,而是为每个版本创建一个目录,并将IIS应用程序重新分配到新路径 . 这有几个好处:
如果需要,快速恢复
无需停止IIS或应用程序池以避免锁定问题
没有旧文件导致问题的风险
或多或少的零停机时间(通常只是在新的appdomain初始化时暂停)
我们遇到的唯一问题是,如果您不重新启动应用程序池并依赖自动appdomain开关,则会缓存资源 .