Capistrano для развертывания приложения рельсов - как справиться с длительными миграциями? - PullRequest
25 голосов
/ 11 февраля 2010

Таким образом, я использую Capistrano для развертывания приложения rails на моем производственном сервере (apache + passenger), и в данный момент развертывание обычно происходит в следующем порядке:

$cap deploy
$cap deploy:migrations

Меня удивило, скажем, мойdb: для выполнения миграций потребовалось много времени на производственном сервере (большой рефакторинг схемы db) - в этом случае, что лучше всего использовать с Capistrano?Что произойдет, если пользователи подключатся к моему приложению во время развертывания?Стоит ли изящно отправлять пользователей на статическую страницу-заполнитель во время обновления базы данных?Capistrano справляется с этим автоматически?Нужно ли кодировать рецепт, чтобы помочь с этим?Или внутренние механизмы рельсов / пассажиров означают, что мне не нужно беспокоиться об этом конкретном случае?

Спасибо.

Ответы [ 2 ]

36 голосов
/ 11 февраля 2010

Вам следует открыть страницу обслуживания, если приложение какое-то время не будет доступно. Я использую эту задачу 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.

5 голосов
/ 11 февраля 2010

Мои производственные развертывания обычно следуют этому процессу:

  1. cap production deploy:web:disable, который направляет все запросы на статическую страницу обслуживания
  2. cap production deploy
  3. миграций и т. Д., Тестирование каждого сервера по отдельности, чтобы убедиться, что все в порядке
  4. cap production deploy:web:enable чтобы сайт работал как надо

Ответ Джона Топли дает вам немного полезной информации.

...