apache Capistrano 部署 rails 应用程序——如何处理长时间的迁移?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2244263/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 18:45:41  来源:igfitidea点击:

Capistrano to deploy rails application - how to handle long migrations?

ruby-on-railsapachepassengercapistrano

提问by Clinton

So I am using Capistrano to deploy a rails application to my production server (apache+passenger) and at the moment deployment usually goes along the lines:

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

$cap deploy
$cap deploy:migrations

It got me wondering, let's say my db:migrations took a long time to execute on the production server (a big refactor of the db schema) - in this case what is best practice with Capistrano? What happens if users are connected to my application at the time of deployment? Should I gracefully send users to a static placeholder page while the database is being updated? Does Capistrano handle this automagically? Do I need to code up a recipe to help with this? Or does the internal mechanisms of rails / passenger mean that I don't have to worry at all about this particular case?

这让我想知道,假设我的 db:migrations 在生产服务器上执行需要很长时间(对 db 模式进行了一次重大重构)——在这种情况下,Capistrano 的最佳实践是什么?如果用户在部署时连接到我的应用程序,会发生什么情况?我应该在更新数据库时优雅地将用户发送到静态占位符页面吗?Capistrano 会自动处理吗?我需要编写一个食谱来帮助解决这个问题吗?或者rails/passenger的内部机制是否意味着我完全不必担心这种特殊情况?

Thanks.

谢谢。

回答by John Topley

You should put up a maintenance page if the application is not going to be available for a while. I use this Capistrano task:

如果应用程序暂时不可用,您应该建立一个维护页面。我使用这个 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

The app/views/admin/maintenance.html.erbfile should contain:

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>

The final step is to configure the Apache virtual host with some directives to look for the maintenance.htmlfile and redirect all requests to it if it's present:

最后一步是使用一些指令配置 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>

To put the application into maintenance mode, run cap deploy:web:disableand to make it live again do cap deploy:web:enable.

要将应用程序置于维护模式,请运行cap deploy:web:disable并使其再次生效,请执行以下操作cap deploy:web:enable

回答by dylanfm

My production deploys generally follow this process:

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

  1. cap production deploy:web:disablewhich directs all requests to a static maintenance page
  2. cap production deploy
  3. migrations etc, testing each of the servers individually to make sure things are OK
  4. cap production deploy:web:enableto make the site work as it should
  1. cap production deploy:web:disable将所有请求定向到静态维护页面
  2. cap production deploy
  3. 迁移等,分别测试每个服务器以确保一切正常
  4. cap production deploy:web:enable使网站正常工作

John Topley's response gives you some good in depth info here.

John Topley 的回复在这里为您提供了一些很好的深入信息。