Capistrano 入门
第9章 切换至维护页面
此章对 Capistrano 的 deploy:web:disable 和 deploy:web:enable 任务进行说明
根据 cap -T 表示的说明,各种任务的目的如下:
deploy:web:disable-- 使访问者看到维护页面。deploy:web:enable-- 可以再次通过web搜索应用程序。
嗯,看起来似乎很便利,但是接下来会变成什么却毫无头绪。让我们来看看源代码(省略一部分)。
namespace :deploy do
namespace :web do
task :disable, :roles => :web, :except => { :no_release => true } do
require 'erb'
on_rollback { run "rm #{shared_path}/system/maintenance.html" }
reason = ENV['REASON']
deadline = ENV['UNTIL']
template = File.read(File.join(File.dirname(__FILE__), "templates", "maintenance.rhtml"))
result = ERB.new(template).result(binding)
put result, "#{shared_path}/system/maintenance.html", :mode => 0644
end
task :enable, :roles => :web, :except => { :no_release => true } do
run "rm #{shared_path}/system/maintenance.html"
end
end
end
deploy:web:disable 任务的内容,一句话,就是用 ERB 生成希望作为维护页面显示的 HTML 文件,并把这个写入 #{shared_path}/system/maintenance.html 文件。
作为维护页面的模板 maintenance.rhtml 已存在。因为 File.dirname(__FILE__) 是这个源代码的某个目录,便成了 Capistrano 的安装目录(根据环境不同,/usr/lib/ruby/gems/1.8/gems/capistrano-2.3.0/等等)下的lib/capistrano/recipes/templates/maintenance.rhtml 。因为还没有指定模板的变量,所以想准备好单独的维护页面的话(这个当然是想准备的),参考此代码,自己写任务,添加至 config/deploy.rb 。
然后,deploy:web:enable 任务删除这个文件。
通常,shared_path 是变量 :deploy_to 指定目录下的 shared 目录。也就是说,在 /var/rails/ballad 部署的话,/var/rails/ballad/shared/system/maintenance.html 这个文件便会有问题。
这个文件如果存在的话,可以只凭这个让访问者看到维护页面这样的话说起来很简单,其实并非如此。
还有必要同 Apache 的 mod_rewrite 指令进行一些斗争。
我看见 mod_rewrite 就会变得有些郁闷。mod_rewrite 是瑞士军刀,也是黑魔术(voodoo)(Apache module mod_rewrite)。它能够灵活的进行任何设定,这种奇妙的语法真让我着迷。
好啦。
不管怎样,在 httpd.conf 做如下输入的话,deploy:web:disable 任务便可执行了。
<VirtualHost *:80>
ServerName ballad.example.com
DocumentRoot /var/rails/ballad/current/public
ErrorLog /var/log/httpd/ballad-error_log
CustomLog /var/log/httpd/ballad-access_log combined env=!nolog
<Directory /var/rails/ballad/current/public>
Order Deny,Allow
Allow from All
</Directory>
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{REQUEST_URI} !^/images/
RewriteCond %{REQUEST_URI} !^/javascripts/
RewriteCond %{REQUEST_URI} !^/stylesheets/
RewriteRule ^.*$ /system/maintenance.html [L]
RewriteRule ^/(images|javascripts|stylesheets)/(.*)$ /$1/$2 [L]
ProxyRequests Off
ProxyPass / balancer://ballad_cluster/
<Proxy balancer://ballad_cluster/>
BalancerMember http://127.0.0.1:3000
BalancerMember http://127.0.0.1:3001
BalancerMember http://127.0.0.1:3002
BalancerMember http://127.0.0.1:3003
</Proxy>
</VirtualHost>
让我们来尝试一下黑魔法的说明吧。
首先,使用 RewriteEngine On 让 mod_rewrite 有效。
接下来,在RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f 上,设定
如果
%{DOCUMENT_ROOT}/system/maintenance.html文件存在
这样的条件。在%{DOCUMENT_ROOT} 中,嵌入以上声明的值 /var/rails/ballad/current/public 。
接下来3行的 RewriteCond 设定
如果不是到 /images 或 /javascripts 或 /stylesheets 目录的文件的搜索
这样的条件。处于URI路径模式之前的! 表示否定。
接下来的 RewriteRule ^.*$ /system/maintenance.html [L] 是,
通过正则表达式将匹配 ^.*$ 的路径改写成 /system/maintenance.html
</blockquote>
的意思。这个正则表达式匹配所有路径,所以实际上对于所有的搜索,维护页面都会显示。
这行末尾的 [L] 是“仅做此 URL 的改写”的意思。顺便说一下,“L”是“Last rule”的略语。
接下来的 RewriteRule ^/(images|javascripts|stylesheets)/(.*)$ /$1/$2 [L] 是,
搜索/images 或 /javascripts 或 /stylesheets 目录中的文件,则返回原样
的意思。这里也添加了 [L] 标志,所以这样的对目录中文件的搜索,通常(无论是否在维护中)由 Apache 自己处理。这是为了在维护页面中也能显示图像等,但也有减轻 Rails 应用程序负荷的效果。
这样说明的话,会感觉很简单。但是,读取 mod_rewrite 的文档却相当困难。只推荐给以“吃苦耐劳”为座右铭的人士。
ProxyRequests Off 以下的记述,是为了将 Apache 作为负载平衡器(反向代理)使用。这和这一章的内容没有太大的关系,是向在本地主机的 3000 号至 3003 号端口中运行的Rails程序转送了请求。maintenance.html 不存在(即一般状态)的状态下,这种设定便运行,使 Rails 程序在网站访问者中可见。
那么,尝试执行 deploy:web:disable 任务。
% cap deploy:web:disable
* executing `deploy:web:disable'
servers: ["alpha.oiax.jp"]
** sftp upload #<StringIO:0xb7855b6c> -> /var/rails/ballad/shared/system/maintenance.html
[alpha.oiax.jp] /var/rails/ballad/shared/system/maintenance.html
[alpha.oiax.jp] done
* sftp upload complete
在浏览器中打开 http://ballad.example.com/(实际不存在),即显示出维护页面。
在屏幕上显示的信息中可以看到 sftp 这个文字。这是因为维护页面在本地主机(你自己的电脑)上生成后被发送到远程主机上了。
接下来执行 deploy:web:enable 任务。
% cap deploy:web:enable
* executing `deploy:web:enable'
* executing "rm /var/rails/ballad/shared/system/maintenance.html"
servers: ["alpha.oiax.jp"]
[alpha.oiax.jp] executing command
command finished
啊,回复原状了!!
真让人兴奋。
(2008/06/03)
- 前言
- 第1章 安装 (2008/03/24)
- 第2章 SSH公钥的设置 (2008/03/25)
- 第3章 Windows环境下的 Capistrano (2008/03/26)
- 第4章 capify (2008/03/27)
- 第5章 目标主机的准备 (2008/03/28)
- 第6章 deploy:update (2008/03/29)
- 第7章 Rails应用程序的启动、停止、重启 (2008/05/17)
- 第8章 deploy:rollback 与 deploy:cleanup (2008/05/18)
- 第9章 切换至维护页面 (2008/06/03)

