Capistrano ver.3 tasks for puma

Capistrano を version 3 にしようとしてつまづいた

ずいぶん変わっているので、各所でつまづきの声が聞こえています。

しかし Rails から切り離されてることでシンプルになって汎用性が上がり、withintest など便利なメソッドも使えて良い感じ!

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 本家のものを流用できるはず…

Windows に MinGW と mintty を入れてシェル環境改善


何をするにしてもシェルがしょぼいとやる気を削がれます。 私用の Windows をもうちょっと使いやすくしたい。

やりたいこと

  • Git を使いたい。
  • 普段は Unix 系の仕事が主なので(PowerShellではなく)Unix系がいい。
  • cmd.exe よりカッコイイ見た目がいい。

正直 Cygwin で満たせるけど、もっとシンプルにしたかったので MinGW & mintty を使ってみます。Git も後からいれる。

Cygwin のようにフル機能は使えなくても、起動の速い MinGW Shell で最低限の作業ができるだけでだいぶ良いのです。

こんな

透過できること、フォント設定できる、Ctrl +- で拡大縮小できればだいたい満足。

mingw-mintty

やったこと

MinGW Shell & mintty

ダウンロードしてインストール。

http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/

最新2012ですか… mingw-get-inst-20120426.exe をインストールし MinGW Shell を起動して

$ mingw-get update
$ mingw-get upgrade
$ mingw-get install mintty

カンタン!ついでに ssh もこっちでインストールしとく。

$ minwg-get install msys-openssh

そして mintty を起動。

$ mintty.exe

起動したらタスクバーにピン止めする。ここまでの状態だと、シェルが sh で起動してしまうので プロパティで実行コマンド mintty.exe の後ろにハイフン-をつける。これでログインシェルとして起動する。

prop of shortcut

Git

Git は msysgit とかじゃなくて、 http://git-scm.com/downloads のものを使う。で、Git に PATH が通るようにインストール。

git path

この状態で、PATH はこんな感じになってるはず。

$ echo $PATH
.:/usr/local/bin:/mingw/bin:/bin:
(...中略...)
:/c/Program Files (x86)/Git/cmd:...

実行できるか確認。

$ which git
/c/Program Files (x86)/Git/cmd/git.exe
$ git --version
git version 1.8.3.msysgit.0

$ which ssh
/bin/ssh.exe
$ ssh -v
OpenSSH_5.4p1, OpenSSL 1.0.0 29 Mar 2010
...

よさげ!

ここまで下準備。さらにガッツリ作業したいとき用にLinux VMを併用するつもり。