【问题标题】:How to get started deploying PHP applications from a subversion repository?如何开始从 subversion 存储库部署 PHP 应用程序?
【发布时间】:2010-10-22 11:11:47
【问题描述】:

我听说过“部署应用程序”这个短语,这听起来比将单个更改的文件上传到服务器要好/更容易/更可靠,但我不知道从哪里开始。

我有一个受版本控制的 Zend Framework 应用程序(在 Subversion 存储库中)。如何“部署”我的应用程序?如果我有一个不想覆盖的“上传”目录该怎么办?

我通过第三方托管我的应用程序,所以除了 FTP 之外我知道的不多。如果其中任何一项涉及登录我的服务器,请解释该过程。

【问题讨论】:

  • 我觉得这是一个有趣的问题。我永远不会实现自动更新,但我想要的有点像一个签出的实时副本,我可以切换它等等......所以我想要一个工作副本然后从那里上传到实时服务器而不是在服务器上有一个实时“工作”副本。应该是这样的,但我从未尝试过。
  • 我记得听说 stackoverflow 也在做同样的事情
  • 我最近听到(来自 ITC)关于这个问题的播客也提到了 timothyfitz.wordpress.com/2009/02/10/… 的博客条目/跨度>

标签: php svn zend-framework deployment setup-deployment


【解决方案1】:

自动部署 + 运行测试到暂存服务器称为持续集成。这个想法是,如果您签入破坏测试的内容,您会立即收到通知。对于 PHP,您可能需要查看 XincphpUnderControl

您通常想要自动部署到生产环境。正常的做法是编写一些脚本来自动执行任务,但您仍然需要手动启动。您可以为此使用诸如Phing 之类的框架或其他构建工具(一个流行的选择是Capistrano),但您也可以将几个shell 脚本组合在一起。我个人更喜欢后者。

脚本本身可以做不同的事情,具体取决于您的应用程序和设置,但一个典型的过程是:

  • SSH 到生产服务器。其余命令通过 ssh 在生产服务器上运行。
  • 运行svn export svn://path/to/repository/tags/RELEASE_VERSION /usr/local/application/releases/TIMESTAMP
  • 停止服务(Apache、守护进程)
  • 运行unlink /usr/local/application/current && ln -s /usr/local/application/releases/TIMESTAMP /usr/local/application/current
  • 运行ln -s /usr/local/application/var /usr/local/application/releases/TIMESTAMP/var
  • 运行/usr/local/application/current/scripts/migrate.php
  • 启动服务

(假设您的应用程序位于/usr/local/application/current

【讨论】:

    【解决方案2】:

    我不建议自动更新。仅仅因为您的单元测试通过并不意味着您的应用程序是 100% 工作的。如果有人在没有任何新单元测试的情况下签入一个随机的新功能,并且该功能不起作用怎么办?您现有的单元测试可能会通过,但无论如何该功能可能会被破坏。您的用户可能会看到完成了一半的事情。通过签入自动部署,您可能在几个小时内都不会注意到是否有不应该有的东西让它生效。

    无论如何,如果您真的想要,进行自动部署并不难。你需要一个签到后挂钩,实际上步骤是:

    1) 从最近的签到中导出 2)上传导出到生产服务器 3) 解压/配置新上传的导出

    我总是手动执行最后的步骤。通常它就像 SVN 导出、压缩、上传、解压缩、配置一样简单,最后两个步骤我只是将几个 bash 命令别名在一起来执行。然后,我将根应用程序目录换成新的,确保我保留旧的作为备份,这很好。

    如果您对在错误自动上线之前发现错误的能力充满信心,那么您可以考虑使该过程自动化。不过,它给了我摇摆不定的感觉。

    【讨论】:

    • 我同意你关于自动更新的建议。但是,我会用一些自动过程代替您的手动更新过程。步骤越少,出错的可能性就越小。我们每天进行十几次部署,并尽可能地自动化以减少错误。我可以为此推荐 Webistrano,它主要执行您的步骤,但自动且更灵活。如果您的需求更简单,使用 rsync 的脚本可能会很好。
    【解决方案3】:

    在我的 webdev 公司,我们最近开始使用 Webistrano,这是流行的 Capistrano 工具的 Web GUI。

    我们想要一个易于使用、快速部署的工具,它具有集中式界面、问责制(谁部署了哪个版本)、回滚到以前的版本,最好是免费的。 Capistrano 是众所周知的 Ruby on Rails 应用程序的部署工具,但不是集中式的,主要针对 Rails 应用程序。 Webistrano 通过 GUI、问责制对其进行了增强,并添加了对 PHP 部署的基本支持(使用“纯文件”项目类型)。

    Webistrano 本身就是一个 Ruby on Rails 应用程序,您可以安装在开发或登台服务器上。您为每个网站添加一个项目。为每个项目添加阶段,例如 Prod 和 Dev。

    每个阶段可以有不同的服务器部署到不同的设置。编写(或修改)一个“食谱”,这是一个告诉 capistrano 要做什么的 ruby​​ 脚本。在我们的例子中,我只是使用了提供的配方并添加了一个命令来创建指向共享上传目录的符号链接,就像你提到的那样。

    当您单击“部署”时,Webistrano 会通过 SSH 连接到您的远程服务器,对代码进行 svn 检出,并执行您需要的任何其他任务,例如数据库迁移、符号链接或清理以前的版本。当然,这一切都可以调整,毕竟只是脚本而已。

    我们对此非常满意,但我花了几天时间来学习和设置,尤其是因为我不熟悉 Ruby 和 Rails。尽管如此,我还是强烈推荐它用于中小型公司的生产用途,因为它被证明非常可靠、灵活,并且为我们节省了很多倍的初始投资。不仅可以加快部署速度,还可以减少错误/事故。

    【讨论】:

      【解决方案4】:

      这种事情就是你所说的“持续集成”。 Atlassian Bamboo(成本)、Sun Hudson(免费)和 Cruise Control(免费)都是流行的选项(按我的喜好排序)并且支持处理 PHPUnit 输出(因为 PHPUnit 支持 JUnit 输出)。

      部署工作可以通过构建后触发器来完成。像这个线程上的其他人一样,在签入(和测试通过)时进行自动部署之前,我会非常谨慎。

      【讨论】:

        【解决方案5】:

        检查 fredistrano,这是一个 capistrano 克隆 效果很好(安装有点混乱,但毕竟运行良好)

        http://code.google.com/p/fredistrano/

        【讨论】:

          【解决方案6】:

          要处理上传,经典的解决方案是将实际目录移出主网络空间,仅将其留给要签出的新版本(就像我在下面的脚本中所做的那样),然后使用 Apache 来“别名”它作为网站的一部分恢复原状。

          Alias /uploads /home/user/uploads/
          

          但是,如果您对服务器没有太多的控制权,那么您的选择就更少了。

          我有一个脚本,用于将给定脚本部署到开发/实时站点(它们都在同一台服务器上运行)。

          #!/bin/sh
          
          REV=2410
          REVDIR=$REV.20090602-1027
          
          REPOSITORY=svn+ssh://topbit@svn.example.com/var/svn/website.com/trunk
          IMAGES=$REVDIR/php/i
          STATIC1=$REVDIR/anothersite.co.uk
          
          svn export --revision $REV  $REPOSITORY $REVDIR
          
          mkdir -p $REVDIR/tmp/templates_c
          chown -R username: $REVDIR
          chmod -R 777       $REVDIR/tmp $REVDIR/php/cache/
          chown -R nobody:   $REVDIR/tmp $REVDIR/php/cache/ $IMAGES
          dos2unix $REVDIR/bin/*sh  $REVDIR/bin/*php
          chmod 755 $REVDIR/bin/*sh $REVDIR/bin/*php
          
          # chmod -x all the non-directories in images
          find $IMAGES -type f -perm -a+x | xargs -r chmod --quiet -x
          find $STATIC1 -type f -perm -a+x | xargs -r chmod --quiet -x
          
          ls -l $IMAGES/* | grep -- "-x"
          
          rm dev && ln -s $REVDIR dev
          

          我输入了修订号,以及用于签出目录名称的日期/时间。中间的 chmod 也使图像的权限正常,因为它们也符号链接到我们的专用图像服务器。

          最后发生的事情是旧的符号链接 .../website/dev/ 重新链接到新签出的目录。 Apache 配置的文档根目录为 .../website/dev/htdocs/

          还有一个匹配的 .../website/live/htdocs/ docroot,同样,“live”是另一个符号链接。这是我的另一个脚本,它将删除实时符号链接,并将其替换为 dev 指向的任何内容。

          #!/bin/sh
          # remove live, and copy the dir pointed to by dev, to be the live symlink
          rm live && cp -d dev live
          

          我只是每隔几个数据推送一个新版本的网站,所以您可能不想每天使用几次(我的 APC 缓存不会喜欢该网站的多个版本),但对我来说,我发现这对于我自己的部署来说是没有问题的。

          【讨论】:

            【解决方案7】:

            3 年后,我对部署最佳实践有了一些了解。我目前使用一个名为 Capistrano 的工具,因为它易于设置和使用,并且可以很好地处理很多默认设置。

            自动部署过程的基本原理如下:

            1. 您的代码已准备好投入生产,因此它被标记为发布版本:v1.0.0
            2. 假设您已经配置了部署脚本,您可以运行脚本,指定您刚刚创建的标签。
            3. 脚本 SSH 连接到具有以下目录结构的生产服务器:

              /your-application
                  /shared/
                      /logs
                      /uploads
                  /releases/
                      /20120917120000
                      /20120918120000  <-- latest release of your app
                          /app
                          /config
                          /public
                          ...etc
                  /current --> symlink to latest release
              
              Your Apache document root should be set to /your-application/current/public
              
            4. 脚本在发布目录中创建一个具有当前日期时间的新目录。在该目录中,您的代码将更新为您指定的标记。

            5. 然后删除原始符号链接并创建一个新符号链接,指向最新版本。

            需要在版本之间保留的内容放在共享目录中,并为这些共享目录创建符号链接。

            【讨论】:

            • 我听到有人反对 PHP 应用程序部署中的符号链接:当部署发生时,应用程序可能位于 requireing 一组类文件的中间。这会导致少数用户使用不兼容的更改(PHP 不会知道这一点,因为每个文件的前后状态都在同一路径上)。编写 Apache vhost 配置文件的重新生成脚本以直接指向发布路径,然后执行优雅的reload 会更安全吗?
            【解决方案8】:

            这取决于您的应用程序以及测试的可靠性。

            在我工作的地方,所有内容都会被检入存储库以供审核,然后发布。

            从存储库中自动更新对我们来说并不明智,因为有时我们只是签入以便其他开发人员可以提取更高版本并合并其中的更改。

            要执行您所说的操作,需要进行某种辅助签入和签出,以允许主要签入区域的开发人员之间进行协作。虽然我对此一无所知,也不知道它是否可能。

            还有需要处理的分支和其他类似功能的问题。

            【讨论】:

            • 嗯,你可以有一个发布标签和一个提交后挂钩,它只部署已被标记为稳定的修订。 IE。随心所欲地提交、分支和标记,但仅在遇到 stable 关键字时部署。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-24
            • 1970-01-01
            • 1970-01-01
            • 2010-09-16
            • 1970-01-01
            相关资源
            最近更新 更多