自定义capistrano维护页面

capistrano是目前最为流行的Rails部署工具,不过一旦进入产品阶段,我们可能希望在部署时显示一个“站点正在维护中”的页面,而不是正在升级中的应用,当前版本(2.5)的capistrano提供了两个内置任务来完成这一工作,它们就是deploy:web:disable和 deploy:web:enable,如果你仔细查看capistrano的部署目录,会在current/public目录下发现一个system目录,它是一个指向shared/system的链接,因此我们首先需要在shared目录下建立system目录,capistrano使用它来存放维护页面。

server$ mkdir deploy/shared

现在如果我们执行cap deploy:web:disable,capistrano会通过sftp上传一个默认的站点维护页面到shared/system /maintenance.html,而deploy:web:enable则会将这个页面删除,但是这个任务本身并不能将应用屏蔽掉,我们需要修改前端服务器的rewrite规则。

如果你使用nginx,那么加入下面几行到你的nginx.conf:


server {
  root /current/deploy/path/public;
  if (-f $document_root/system/maintenance.html) {
    set $maintenance 1;
  }
  if ($request_uri ~* (jpg|jpeg|gif|js|css)$) {
    set $maintenance 0;
  }
  if ($maintenance) {
    rewrite ^(.*)$ /system/maintenance.html last;
    break;
  }
  location / {
    ....

这样nginx会首先判断维护页面是否存在,如果存在,则将所有清除都转向维护页面,如果使用apache,则需要修改.htaccess(未验证):

RewriteCond %{REQUEST_URI} !\.(css|jpg|js|gif|png)$
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [L]

如果你想要这一切自动进行,那么你可以将这两个任务加入deploy任务:


namespace :deploy do
  desc "Default deploy will update the code without migrate the database and restart the servers"
  task :default do
    # put up the maintenance screen
    web.disable
    transaction do
      update_code
      symlink
      copy_configs
    end
    restart
    # remove the maintenance screen
    web.enable
  end
end

如果你想要自定义维护页面,可以通过覆盖默认的deploy:web:disable任务实现:


namespace :deploy do
  namespace :web do
    task :disable do
      on_rollback { delete "#{shared_path}/system/maintenance.html" }
      require 'rubygems'
      require 'haml'
      template = File.read("./app/views/layouts/maintenance.html.haml")
      haml = Haml::Engine.new(template)
      maintenance = haml.render(Object.new,
        :deadline => ENV['UNTIL'],
        :reason => ENV['REASON'])
      put maintenance, "#{shared_path}/system/maintenance.html",
        :mode => 0644
    end
  end
end

这段代码渲染了layouts/maintenance.html.haml,你可以根据自己的需要定义它,这里我们传入了两个变量,一个指定原因,一个指定恢复时间:


%h1
  We're currently down for
  = reason ? reason : "maintenance"
  as of
  = Time.now.strftime("%H:%M %Z")
%p
  Sorry for the inconvenience. We'll be back
  = deadline ? "by #{deadline}" : "shortly"
  Please email us if you need to get in touch.

你可以在执行deploy:web:disable之前设定这两个变量:

UNTIL=”16:00 MST” REASON=”a database upgrade” cap disable_web

参考:

This entry was posted in 部署. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.
  • http://welog.org king

    但我在使用capistrano2.5.0时 cap capify . 都找不到,奇怪的问题。

无觅相关文章插件,快速提升流量