如何从subversion存储库开始部署PHP应用程序?

时间:2009-04-28 23:40:59

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

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

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

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

9 个答案:

答案 0 :(得分:21)

自动部署+运行测试到登台服务器称为持续集成。我们的想法是,如果你签入了破坏测试的东西,你会立即得到通知。对于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

答案 1 :(得分:7)

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

无论如何,如果你真的想要自动部署就不会那么困难了。你需要一个后检查挂钩,实际上步骤是:

1)从最近的办理登机手续办理出口 2)上传导出到生产服务器 3)解压缩/配置新上传的导出

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

如果您对自己在自动上线之前发现错误的能力充满信心,那么您可以考虑自动化该过程。它给了我jibbly-jibblies。

答案 2 :(得分:5)

这是一篇关于使用Subversion部署Web项目的优秀文章 - 它回答了很多问题。

http://athleticsnyc.com/blog/entry/on-using-subversion-for-web-projects

答案 3 :(得分:4)

在我的webdev公司,我们最近开始使用Webistrano,它是受欢迎的Capistrano工具的Web GUI。

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

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

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

单击“部署”时,Webistrano将SSH连接到远程服务器,执行svn检查代码以及所需的任何其他任务,例如数据库迁移,符号链接或清除以前的版本。所有这些都可以调整,毕竟,它只是编写脚本。

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

答案 4 :(得分:1)

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

可以使用post build触发器完成部署工作。与此线程中的其他人一样,在签入(和测试传递)上进行自动部署之前,我会非常谨慎。

答案 5 :(得分:1)

为了处理上传,经典的解决方案是将实际目录移出主网站空间,只留下一个新版本进行检出(就像我在下面的脚本中所做的那样)然后使用Apache来实现'Alias'它作为网站的一部分重新安装到位。

Alias /uploads /home/user/uploads/

如果您没有尽可能多的服务器控制权,那么您的选择就会减少。

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

#!/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缓存不会比网站的几个版本更好),但对我来说,我发现这对我自己的部署来说非常无问题。

答案 6 :(得分:1)

检查fredistrano,这是一个capistrano克隆 效果很好(安装有点令人困惑,但毕竟运行得很好)

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

答案 7 :(得分:1)

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. 该脚本使用当前日期时间在releases目录中创建一个新目录。在该目录中,您的代码将更新为您指定的标记。

  5. 然后删除原始符号链接并创建一个新的符号链接,指向最新版本。
  6. 需要在发行版之间保存的内容位于共享目录中,并且会为这些共享目录创建符号链接。

答案 8 :(得分:0)

这取决于您的应用程序以及测试的稳固程度。

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

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

要做你正在谈论的事情,需要进行某种二次检查,以便在主要检查区域内的开发人员之间进行协作。虽然我对此一无所知,或者甚至不知道。

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