Capistrano & RVM - Czego nie przegapić przy konfiguracji?
Twórcy aplikacji często dużo czasu poświęcają na cykliczny deployment ich najnowszej wersji. Z reguły polega on na pobraniu najnowszej wersji aplikacji, migracji bazy danych, kompilacji styli i skryptów JS oraz restarcie serwera aplikacyjnego. Od ponad 10 lat Capistrano umożliwia im to nie zawsze łatwe zadanie.
Capistrano służy do automatyzacji powtarzających się procedur, głównie na zdalnych maszynach. Łączy się do nich i wykonuje odpowiednie komendy, zdefiniowane w konfiguracji projektu lub dostępne w obszernej bazie rozszerzeń dostępnych w RubyGems.
Dzięki temu możemy automatyzować na przykład deployment aplikacji stworzonych w Ruby on Rails, ich diagnozę, aktualizację certyfikatów SSL bądź całych systemów z rodziny UNIX.
Dzisiaj dowiemy się, jak umożliwić Capistrano 3 deploy aplikacji stworzonych w Railsach, korzystającej z RVM-a (>= 1.0).
Pierwszym krokiem jest doinstalowanie gem-a który instaluje RVM-a-a dla konkretnego deployu:
// Gemfile
gem 'rvm1-capistrano3', require: false
Ten gem zainstaluje i skonfiguruje RVM-a, działa bezproblemowo dla Railsów, przynajmniej od czwórki wzwyż. Po doinstalowaniu gema, wymagamy go w Capfile’u:
// Capfile
require 'rvm1/capistrano3'
a następnie “dogrywamy” go do procedury deploymentu:
// config/deploy/production.rb
before 'deploy', 'rvm1:install:rvm'
before 'deploy', 'rvm1:install:ruby'
Tutaj może pojawić się problem braku Bundlera w gemsecie świeżo utworzonym przez RVMa. Ręczna instalacja go w każdej nowo deployowanej aplikacji mocno kontrastuje z RVM-em robiącym wszystko za nas. Możemy ten problem rozwiązać na dwa sposoby:
-
Wyzwalać instalację Bundlera poprzez
gem install bundler
przy każdym deployu:namespace :deploy do task :install_bundler do on roles(:app) do within File.join( fetch(:deploy_to), 'releases', capture( "ls #{File.join(fetch(:deploy_to), 'releases')}" ).split("\n").sort.last ) do execute :rvm, :'.', :do, :gem, :install, :bundler end end end end
-
Lub wymusić w RVM-ie instalację Bundlera dla każdego nowego gemsetu:
namespace :deploy do task :rvm_force_bundler do on roles(:app) do execute "grep -qF '^bundler' ~/.rvm/gemsets/global.gems || echo 'bundler' >> ~/.rvm/gemsets/global.gems" end end end
Mogłoby się wydawać, że drugi sposób jest bardziej jednorazowy – niestety, gem wprowadzający wsparcie RVM-a za każdym deploymentem czyści config RVMa w którym można zdefiniować instalowane gemy. Rozwiązać można to poprzez wyzwalanie komendy dopisującej Bundlera do listy przy każdym deployu. Praktycznie, wychodzi na to samo.
Ważne jest by w repozytorium projektu były pliki .ruby-version
i .ruby-gemset
i by zawierały odpowiednią treść.
Od teraz po użyciu cap production deploy
(gdzie production
to nasz stage), Capistrano będzie używał RVM-a dla tego projektu.
Moim zdaniem Capistrano jest naprawdę zaawansowanym narzędziem, które śmiało mogę uznać za niezbędnik każdego twórcy aplikacji - a także administratora.
To pierwszy z serii postów na jego temat - już niebawem przedstawię Wam kolejną porcję informacji, o których mogliście jeszcze nie mieć pojęcia.
Bazowane na witrynach Capistrano i rvm1-capistrano3.
Logo Capistrano stworzone przez Tom Clements, Lee Hambley. Opublikowane na licencji MIT.