2010-02-11 7 views
25

Je me sers Capistrano pour déployer une application de rails à mon serveur de production (apache + passagers) et au déploiement moment va généralement le long des lignes:Capistrano pour déployer l'application de rails - comment gérer de longues migrations?

$cap deploy 
$cap deploy:migrations 

Il m'a fait demander, disons que mon db: migrations a pris beaucoup de temps à exécuter sur le serveur de production (un grand refactor du schéma db) - dans ce cas, quelle est la meilleure pratique avec Capistrano? Que se passe-t-il si les utilisateurs sont connectés à mon application au moment du déploiement? Dois-je envoyer gracieusement des utilisateurs à une page d'espace réservé statique pendant la mise à jour de la base de données? Est-ce que Capistrano gère cela automagiquement? Ai-je besoin de coder une recette pour m'aider? Ou est-ce que les mécanismes internes des rails/passagers signifient que je n'ai pas à m'inquiéter du tout de ce cas particulier?

Merci.

Répondre

36

Vous devriez mettre en place une page de maintenance si l'application ne sera pas disponible pendant un certain temps. J'utilise cette tâche 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 

Le fichier app/views/admin/maintenance.html.erb doit contenir:

<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> 

La dernière étape consiste à configurer l'hôte virtuel Apache avec quelques directives pour chercher le fichier maintenance.html et rediriger toutes les requêtes si elle est présente:

<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> 

pour mettre l'application en mode maintenance, exécutez cap deploy:web:disable et faire vivre ag ain do cap deploy:web:enable.

+1

La page de maintenance sera-t-elle desservie par "200 OK" ou "Service 503 temporairement indisponible"? Google pourrait penser, votre contenu précieux pourrait être parti, si vous le servez avec 200 OK. Voir http://googlewebmastercentral.blogspot.com/2011/01/how-to-deal-with-planned-site-downtime.html – iGEL

+1

Bon point, Capistrano lui-même suggère l'extrait suivant pour le .htaccess: https: // gist .github.com/1292705 –

+1

Vous avez oublié la tâche 'enable'! –

5

Ma production déploie suivent généralement ce processus:

  1. cap production deploy:web:disable qui dirige toutes les requêtes vers une page de maintenance statique
  2. cap production deploy
  3. migrations etc, tester chacun des serveurs individuellement pour assurer que les choses sont OK
  4. cap production deploy:web:enable pour que le site fonctionne comme bon lui semble

La réponse de John Topley vous donne quelques bonnes informations en profondeur ici.