Capistrano ver.3 tasks for puma
Capistrano を version 3 にしようとしてつまづいた
ずいぶん変わっているので、各所でつまづきの声が聞こえています。
しかし Rails から切り離されてることでシンプルになって汎用性が上がり、within
や test
など便利なメソッドも使えて良い感じ!
ver.2 までを使っていたら気をつけること
- multistage と color がデフォルトに!
- Rails oriented なツールではない
- ver 2 を流用しようと思わずに一から書き直したほうが早い
- SSHKit をちゃんと読む https://github.com/capistrano/sshkit
- 公式のドキュメントもちゃんと読む。他には Update Guide とかも読む
- scm git しか使えない
deploy_via :copy
は使えないset
したらfetch()
Rails 関連で気をつけること
gem 'capistrano-rails', :require => false
in Gemfile とrequire 'capistrano/rails'
in Capfile しよう- 勝手に
log
とかtmp
とか作ったりしないので、set :linked_dirs, ...
puma タスクを Capistrano 3 対応する
puma 本家の puma/capistrano
は 2014/01時点で Capistrano 3 に対応していないので、悩むより自分で書いたほうがすぐできる感じ。
設定ファイルや start/stop/restart はもともとの puma/capistrano
から、全体の構成はこちらのunicorn向けtaskを真似させてもらっています。
namespace :puma do task :env do set :puma_state, "#{shared_path}/tmp/sockets/puma.state" end def start_puma(bind_addr) execute :bundle, :exec, :puma, start_options(bind_addr) end def stop_puma # Now use 'halt' to stop puma, because 'stop' remains puma process living # and remove pumactl.sock by halves. It seems a puma's bug. # https://github.com/puma/puma/issues/306 execute :bundle, :exec, :pumactl, "-S #{puma_state_path} halt" end def restart_puma(phased_restart = nil) restart = phased_restart ? 'phased-restart' : 'restart' execute :bundle, :exec, :pumactl, "-S #{puma_state_path} #{restart}" end def start_options(bind_addr = '127.0.0.1') if config_file "-q -d -e #{app_env} -C #{config_file}" else "-q -d -e #{app_env} -b 'tcp://#{bind_addr}:3000' -S #{fetch(:puma_state)} --control 'tcp://localhost:3001'" end end def config_file # @ToDo nil end def puma_state_path (config_file ? configuration.options[:state] : nil) || fetch(:puma_state) end def configuration require 'puma/configuration' config = Puma::Configration.new(config_file: config_file) config.load config end desc "Start puma" task :start => :env do on roles(:app) do |host| within current_path do start_puma(host) end end end desc "Stop puma" task :stop => :env do on roles(:app) do within current_path do stop_puma end end end desc "Restart puma" task :restart => :env do on roles(:app) do |host| within current_path do if test("[ -f #{puma_state_path} ]") restart_puma else start_puma(host) end end end end desc "Phased restart puma" task :phased_restart => :env do on roles(:app) do |host| within current_path do if test("[ -f #{puma_state_path} ]") restart_puma('phased-restart') else start_puma(host) end end end end desc "Force clean up puma" task :cleanup => :env do on roles(:app) do if test("[ -f #{puma_state_path} ]") execute <<-EOC kill -9 `grep pid #{puma_state_path} | awk '{print $2;}'` rm -f #{puma_state_path} EOC else execute <<-EOC kill -9 `ps ax | grep ruby | grep puma | awk '{print $1}'` rm -f #{puma_state_path} EOC end end end after 'deploy:publishing', 'puma:restart' end
上記ではアプリ本体、Control Server ともに TCP で立ち上げているが、UNIX ソケット unix://...
でもおっけー。
Config ファイルのロードはテストしていないので省いたけれど、puma 本家のものを流用できるはず…