Capistrano部署rails应用程序 - 如何处理长迁移?

时间:2010-02-11 12:08:14

标签: ruby-on-rails apache passenger capistrano

所以我使用Capistrano将rails应用程序部署到我的生产服务器(apache + passenger),目前部署通常是这样的:

$cap deploy
$cap deploy:migrations

让我想知道,让我说我的db:迁移需要很长时间才能在生产服务器上执行(db模式的一个重构) - 在这种情况下,Capistrano的最佳实践是什么?如果用户在部署时连接到我的应用程序会发生什么?在更新数据库时,我应该优雅地将用户发送到静态占位符页面吗? Capistrano是否自动处理?我是否需要编写配方来帮助解决这个问题?或者铁路/乘客的内部机制是否意味着我根本不必担心这种特殊情况?

感谢。

2 个答案:

答案 0 :(得分:36)

如果应用程序暂时无法使用,您应该建立一个维护页面。我使用这个Capistrano任务:

namespace :deploy do
  namespace :web do
    desc <<-DESC
      Present a maintenance page to visitors. Disables your application's web \
      interface by writing a "maintenance.html" file to each web server. The \
      servers must be configured to detect the presence of this file, and if \
      it is present, always display it instead of performing the request.

      By default, the maintenance page will just say the site is down for \
      "maintenance", and will be back "shortly", but you can customize the \
      page by specifying the REASON and UNTIL environment variables:

        $ cap deploy:web:disable \\
              REASON="a hardware upgrade" \\
              UNTIL="12pm Central Time"

      Further customization will require that you write your own task.
    DESC
    task :disable, :roles => :web do
      require 'erb'
      on_rollback { run "rm #{shared_path}/system/maintenance.html" }

      reason = ENV['REASON']
      deadline = ENV['UNTIL']      
      template = File.read('app/views/admin/maintenance.html.erb')
      page = ERB.new(template).result(binding)

      put page, "#{shared_path}/system/maintenance.html", :mode => 0644
    end
  end
end

app/views/admin/maintenance.html.erb文件应包含:

<p>We’re currently offline for <%= reason ? reason : 'maintenance' %> as of <%= Time.now.utc.strftime('%H:%M %Z') %>.</p>
<p>Sorry for the inconvenience. We’ll be back <%= deadline ? "by #{deadline}" : 'shortly' %>.</p>

最后一步是为Apache虚拟主机配置一些指令,以查找maintenance.html文件并将所有请求重定向到它(如果存在):

<IfModule mod_rewrite.c>
  RewriteEngine On

  # Redirect all requests to the maintenance page if present
  RewriteCond %{REQUEST_URI} !\.(css|gif|jpg|png)$
  RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
  RewriteCond %{SCRIPT_FILENAME} !maintenance.html
  RewriteRule ^.*$ /system/maintenance.html [L]
</IfModule>

要将应用程序置于维护模式,请运行cap deploy:web:disable并重新设置为cap deploy:web:enable

答案 1 :(得分:5)

我的生产部署通常遵循以下流程:

  1. cap production deploy:web:disable将所有请求定向到静态维护页面
  2. cap production deploy
  3. 迁移等,单独测试每个服务器以确保一切正常
  4. cap production deploy:web:enable使网站正常工作
  5. John Topley的回复在这里为您提供了一些很好的深度信息。