Aujourd’hui je vous propose de faire une revue des changements nécessaires pour migrer Capistrano de la version 2 vers la 3 dans une application Rails.
Tout d’abord il faut mettre à jour le Gemfile pour ajuster les gems et les versions à utiliser:
gem 'capistrano', '~> 2.0'
devient:
gem 'capistrano', '~> 3.0'
Il faut aussi rajouter ces 2 gems:
gem 'capistrano-rails', '~> 1.1', require: false
gem 'capistrano-bundler', '~> 1.1', require: false
puisque Capistrano 3 n’intègre plus Rails et Bundler par défaut. Si vous utilisez Passenger, vous voudrez aussi ajouter capistrano-passenger
.
Nous avons aussi les gems correpondantes au gestionnaire de versions de Ruby capistrano-rvm
, capistrano-rbenv
et capistrano-chruby
, qu’il peut être intéressant d’ajouter. Dans mon cas:
gem 'capistrano-rbenv', '~> 2.0', require: false
Il est ensuite conseillé de faire un backup de l’ancienne configuration de Capistrano 2, qui comprend au minimum un Capfile
, un config/deploy.rb
, et en cas de multi-instances les fichiers compris dans config/deploy/
:
mkdir old_cap
mv Capfile old_cap
mv config/deploy.rb old_cap
mv config/deploy/ old_cap
Après un bundle install
, nous pouvons utiliser la nouvelle commande d’installation de Capistrano 3:
bundle exec cap install
On retrouve le Capfile
à la racine du projet, ainsi que config/deploy.rb
et, puisque Capistrano 3 est multi-instances par défaut, config/deploy/staging.rb
et config/deploy/production.rb
.
Voici le Capfile généré:
# Load DSL and set up stages
require 'capistrano/setup'
# Include default deployment tasks
require 'capistrano/deploy'
# Include tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
# https://github.com/capistrano/rvm
# https://github.com/capistrano/rbenv
# https://github.com/capistrano/chruby
# https://github.com/capistrano/bundler
# https://github.com/capistrano/rails
# https://github.com/capistrano/passenger
#
# require 'capistrano/rvm'
# require 'capistrano/rbenv'
# require 'capistrano/chruby'
# require 'capistrano/bundler'
# require 'capistrano/rails/assets'
# require 'capistrano/rails/migrations'
# require 'capistrano/passenger'
# Load custom tasks from `lib/capistrano/tasks' if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
Nous pouvons décommenter les parties qui nous intéressent. Déjà capistrano/bundler
, capistrano/rails/assets
et capistrano/rails/migrations
, puis la gem en rapport avec Passenger si vous l’utilisez, ainsi que la gem correspondante à notre gestionnaire de versions de Ruby.
On peut maintenant remettre en place les anciens fichiers de multi-instances au même endroit dans config/deploy/
, et “merger” les nouveaux fichiers avec les anciens.
Notez que la tache deploy:restart
n’est plus exécutée automatiquement, il faut donc penser à l’appeler:
after 'deploy:publishing', 'deploy:restart'
# ou
namespace :deploy do
after :publishing, :restart
end
Pour les utilisateurs de Passenger ayant intégrés la gem capistrano-passenger
, cet ajout n’est pas nécessaire.
Quelques options ont changées, voici certains changements de définitions à noter:
set :linked_files, %w{ config/database.yml }
linked_dirs
est prévue à cet effetrepository
devient repo_url
set :deploy_via, :remote_cache
n’est plus nécessaire, car le mode :copy
n’est plus présent dans la version 3pty
se définie comme les autres: set :pty, true
verbose
du tableau d’options ssh_options
remplace l’option -v
de la ligne de commande. Elle peut être utile pour trouver les erreurs lors d’un déploiement.set :ssh_options, { verbose: :debug }
Voici quelques exemples de nouveautés apportées par SSHKit:
fetch(:var_name)
et non plus simplement par var_name
on
, qui défini donc cette tache pour un ou plusieurs roleswithin
sert à définir le dossier dans lequel exécuter les commandeswith
run
, mais avec execute
Exemple pour une tache seed
:
desc 'Runs rake db:seed'
task :seed => [:set_rails_env] do
on primary fetch(:migration_role) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :rake, "db:seed"
end
end
end
end
On peut également voir dans le config/deploy.rb
généré:
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
Ici on observe les options in
, limit
et wait
qui servent respectivement à:
in
: pour définir la stratégie d’execution de la commande sur les différents serveurs (options: parallel
, groups
et sequence
)limit
: en cas d’utilisation de l’option groups
, définit la taille du groupewait
: définit le temps d’attente entre 2 envois d’ordres pour les options groups
et sequence
Le “flow” de déploiement de Capistrano 3 est quelque peu simplifié:
deploy:starting - start a deployment, make sure everything is ready
deploy:started - started hook (for custom tasks)
deploy:updating - update server(s) with a new release
deploy:updated - updated hook
deploy:publishing - publish the new release
deploy:published - published hook
deploy:finishing - finish the deployment, clean up everything
deploy:finished - finished hook
et voici celui d’un “rollback”:
deploy:starting
deploy:started
deploy:reverting - revert server(s) to previous release
deploy:reverted - reverted hook
deploy:publishing
deploy:published
deploy:finishing_rollback - finish the rollback, clean up everything
deploy:finished
Une fois le “merge” fini, tout devrait fonctionner comme avant mais avec Capistrano 3. Pour vérifier que tout est ok:
bundle exec cap staging deploy:check
Encore une chose, la tâche cap deploy:cold
destinée au premier déploiement d’une application, a été retiré de Capistrano version 3. Voici une page donnant quelques options pour ce cas.
Terminons par un petit nettoyage, désinstallons l’ancienne gem Capistrano 2:
gem uninstall capistrano --version '<3.0'
Voilà donc la base des changements à connaître et à apporter pour effectuer cette migration, sur laquelle vous devrez sans aucun doute faire quelques ajustements en fonction de votre projet.
L’équipe Synbioz.
Libres d’être ensemble.
Nos conseils et ressources pour vos développements produit.