使用现代化工具 Capistrano 自动部署 PHP 应用代码到生产环境


PHP 代码早期使用 FTP 部署到生产环境,不过这种方式显然不适合集群部署,也不安全,本教程主要讨论如何使用现代化工具自动部署,这种方式简单、可预知结果,而且可逆。

版本控制

把代码纳入版本控制是现代开发人员的基本素养,我们可以使用 Git,也可以使用 SVN,对于应用开发者来说,版本控制有助于记录代码的变化,我们可以把一个时间点的代码标记为发布版本,可以回滚到之前的状态,还可以在单独的分支中实验新功能,而不影响生产环境使用的代码,更重要的是,版本控制有助于自动部署 PHP 应用

自动部署

为了让部署过程变得简单、可预知结果和可逆,一定要自动部署应用,一旦实现自动化,我们无需再担心复杂的部署过程。

让部署变得简单

应该只执行一个简单的命令就能部署应用。

让部署的结果可预知

我们要让部署的结果可预知,部署不应该有意料之外的副作用,如果出错,部署过程会中止,而不影响现有的生产环境代码。

让部署可逆

如果不小心把有问题的代码部署到生产环境,应该有个简单的命令可以回滚到之前稳定的代码版本,这是我们的安全保障。

Capistrano

Capistrano是用于自动部署应用的软件,能让部署达到上面提到的三点要求,Capistrano 运行在本地设备中,通过 SSH 与远程服务器通信,Capistrano 本来是为了部署 Ruby 应用而开发的,不过任何编程语言开发的应用都可以使用,包括 PHP。

Capistrano 的工作原理

Capistrano 会在远程服务器中保存之前部署的应用,而且每次部署的版本放在各自的目录中,Capistrano 会维护五个或更多之前部署的应用,以防需要回滚到早前版本,Capistano 还会创建一个 current/ 目录,通过符号链接指向当前部署的应用所在的目录,在生产服务器中,Capistrano 管理的目录结构类似如下所示:

/
    home/
        deploy/
            apps/
                my_app/
                    current/
                    releases/
                        release1/
                        release2/
                        release3/
                        release4/
                        release5/

把新版应用部署到生产环境时,Capistrano 首先从应用的 Git 仓库获取最新代码,然后把应用的代码放到 releases/ 目录中的一个新子目录中,最后把 current/ 目录的符号链接指向这个新目录。让 Capistrano 回滚到之前的版本时,Capistrano 会把 current/ 目录的符号链接指向 releases/ 目录中存放之前版本的子目录。Capistrano 是一种优雅且简单的部署方案,能让 PHP 应用的部署过程变得简单、可预知结果和可逆。

安装

Capistrano 应该安装在本地设备中,别在远程服务器中安装,安装时还需要 rubygem,OS X系统默认已经有了,执行下述命令安装 Capistrano:

gem install capistrano

配置

安装好 Capistrano 之后,在使用之前,必须初始化项目,打开终端,进入项目的最顶层目录,执行下述命令:

cap install

这个命令会创建一个名为 Capfile 的文件,一个名为 config/ 的目录,以及一个名为 lib/ 的目录。现在,项目的最顶层目录应该有下述文件和目录:

Capfile
config/
    deploy/
        production.rb
        staging.rb
    deploy.rb
lib/
    capistrano/
        tasks/

Capfile 是 Capistrano 的中央配置文件,会聚合 config/ 目录中的配置文件。config/ 目录中存放的是各个远程服务器环境(如测试环境、预发环境、生产环境等)的配置文件。

默认情况下,Capistrano 假设你为应用搭建了多个环境,例如,可能有单独的预发环境和生产环境。Capistrano 在 config/deploy 目录中为每个环境都提供了单独的配置文件,Capistrano 还提供了 config/deploy.rb 配置文件,这个文件用于保存所有环境通用的设置。

在每个环境中,Capistrano 会区分服务器的角色,例如,生产环境可能有 Web 服务器(Nginx)、应用服务器(App)和数据库服务器(DB),只有大规模的应用才有必要使用这种架构,小型 PHP 应用一般在同一台设备中运行 Web 服务器、应用服务器和数据库服务器。

在本教程中,我们只使用 Capitrano 的 web 角色,在 Capistrano 中,角色的作用是把相关的任务组织在一起,只在属于指定角色的服务器中执行这些任务。

config/deploy.rb文件

这个配置文件包含所有环境通用的配置,本教程中,我们大多数 Capistrano 设置都保存在这个文件中:

  • :application:PHP 应用的名称
  • :repo_url:这是 Git 仓库的 URL
  • :deploy_to:远程服务器中应用目录的绝对路径
  • :keep_releases:保留多少个旧版本,回滚用

config/deploy/production.rb文件

这个文件只包含生产环境的设置,这个文件用于定义生产环境的角色,列出属于各个角色的服务器,我们只使用web 角色,而且只有一个服务器属于这个角色,把 config/deploy/production.rb 文件的内容替换成下述代码(记得替换 IP 地址):

role :web, %w[deploy@123.456.78.90]

认证

使用 Capistrano 部署应用之前,我们必须在本地电脑和远程服务器之间,以及远程服务器和 Git 仓库之间建立认证,前面已经讨论了如何使用 SSH 密钥对在本地电脑和远程服务器之间建立认证,在远程服务器和 Git 仓库之间也要使用 SSH 密钥对建立认证。

准备远程服务器

在部署之前,我们需要准备远程服务器,我们要通过 SSH 登录到远程服务器,创建一个目录存放部署的 PHP 应用。deploy 用户必须有这个目录的读写权限,例如:

/
    home/
        deploy/
            apps/
                my_app/

虚拟主机

Capistrano 会创建软链接,把 current/ 目录指向存放当前应用版本的目录。因此,我们要更新 Web 服务器的虚拟主机文档根目录指向 Capistrano 的 current/ 目录。根据上述文件系统结构图,要把虚拟主机的文档根目录改为 /home/deploy/apps/my_app/current/public,这么做的前提是假设 PHP 应用有个 public 目录,并把它当做文档根目录。

依赖的软件

远程服务器不需要 Capistrano,但是需要 Git,而且还需要运行 PHP 应用所需的全部软件,我们可以执行以下命令安装 Git:

#Ubuntu
sudo apt-get install git

#CentOS
sudo yum install git

Capistrano的钩子

Capistrano 允许在部署应用过程中的特定时刻执行我们指定的命令,很多 PHP 开发者都使用 Capistrano 管理应用的依赖,每次使用 Capistrano 部署应用时,我们可以使用 Capistrano 的钩子安装 Composer 依赖。在 config/deploy.rb 文件中添加以下代码:

namespace :deploy do
    desc "Build"
    after :updated, :build do
        on roles(:web) do
            within release_path do
                execute :composer, "install --no-dev --quiet"
            end
        end
    end
end
注:如果使用 Composer 管理依赖,远程服务器中需要安装 Composer。
更多 Capistrano 钩子信息请参考 Capistrano 官网:http://capistranorb.com/documentation/getting-started/flow/

部署应用

正式部署应用之前,需要确保应用代码已提交并推送到 Git 仓库,然后在本地电脑打开终端,进入应用的最顶层目录,执行下面的命令进行部署:

cap production deploy

回滚应用

如果不慎把错误代码提交到生产环境,可以执行下面的命令回到之前的版本:

cap production deploy:rollback

延伸阅读

本教程只是介绍了 Capistrano 的基本使用,还有更多功能有待大家去发掘。除了 Capistrano 之外,还有很多其它部署工具可用:


Vote Vote Cancel Collect Collect Cancel

<< 上一篇: php.ini 配置调优 —— 让 PHP 应用性能维持在更高水平

>> 下一篇: 在 Windows 下安装部署 PHP 7.0 本地开发环境