Capistrano を Rails 以外で使う設定。


Rails と関係ないプロジェクトで Capistrano を使うための設定を作成した。

最小限の設定

SSHでリモートを操作するための、単純な設定の例。ファイル名は Capfile 。

# sshユーザ名
set :user, "username"

# サーバをroleでまとめる
role :abc, "server1.example.com", "user@server2.example.com"
role :xyz, "server3.example.com"

# 全roleで実行。
task :ls do
  run "ls"
end

# 特定のroleで実行。
task :myname, :roles => [:xyz] do
 run "echo " + user
end

svn updateする

もうちょっと複雑にする。リモートでsvn updateを実行する例。

$ sudo gem install capistrano-ext

でgemを足して、 require 'capistrano/ext/multistage' すると、

$ cap xxx taskname

としたときに、config/deploy/xxx.rb を実行前に読み込んでくれるようになる。これを使って、開発用サーバと本番用サーバの設定を切り替える。

デフォルトのタスクを修正する

Capistranoに付いているレシピを利用すると、もっと高度なデプロイ処理が実現できる。

ダウンロードして展開すると以下の階層ができる。

  • Capfile
  • config/
    • deploy.rb
    • deploy/
      • staging.rb
      • live.rb

staging.rbとlive.rbは、multistage用。capistrano-ext が必要。

sudo gem install capistrano
sudo gem install capistrano-ext
修正するタスク

Capfileの load 'deploy' の行でベースのレシピが読み込まれる。

このソースを見ながらRailsに依存する部分を修正をした。デフォルトだと、deployタスクは下のように呼ばれる。

Rails に依存しているのは下の2つのタスク。

finalize_updateを上書きして、自前のシンボリックリンク作成処理を追加した。シンボリックリンクの指定を簡単にするため shared_link メソッドを足した。

また、rollbackタスクでもrestartを呼んでいたので修正。restartなしのrollbackはrollback:codeと同一になったので、rollback:codeの方をタスクごと消した。

不要なタスクの消去

タスクを上書きした時に desc を書かなければタスクは見えなくなる。以下のように使わないタスクを無効・不可視にした。

  [
    # Railsアプリケーション関連のタスクを消します。
    :restart, :start, :stop, :cold, :migrate, :migrations,

    # setupもとりあえず消します。必要なら自分で定義します。
    :setup,
  ].each {|t| task(t){} }
その他デプロイ時に行いたいタスク
after "deploy:finalize_update", "your:originaltask"

のように finalize_update をフックして、追加のタスクを実行するとよい。

ステージ

multistageを使って、

  • staging.rb テスト環境の設定
  • live.rb 本番の設定

の2つのステージを作成した。

set :default_stage, "staging"

のdefault_stageは設定しなくても動く。省略した場合は cap staging deploy のように毎回どのステージか指定しなければならない。

default_stageの設定の有無は、どちらがいいか迷った。本番にデプロイするコマンドは、見た目がなるべく違った方がいいだろうという理由で、デフォルトにstagingを指定してある。

svnのアカウント
set :scm, :subversion
set :scm_username, ENV['SVN_USER'] || ENV['USER']
set :scm_prefer_prompt, true # 毎回パスワードを入力する設定

セキュリティというよりは、操作ミスを避ける目的でパスワードプロンプトを出すようにした。チェックアウトするユーザを固定にして、リモートにパスワードを記憶させてもいい気がする。

バナー

live.rbにバナーの表示を足した。stagingと区別が付きにくくて怖かったので。

puts <<'EOT'
--------------------------------------------------------------------------------
                                _ _           _        
                        __/\__ | (_)_   _____| | __/\__
                        \    / | | \ \ / / _ \ | \    /
                        /_  _\ | | |\ V /  __/_| /_  _\
                          \/   |_|_| \_/ \___(_)   \/  

                               your app name here
--------------------------------------------------------------------------------
EOT

figletのコマンド名が思い出せず苦労した。-cでセンタリング。

figlet -c '* live! *'
設定時のテスト

設定のチェックのために毎回デプロイしてられないので、

task :xxx do
  run "uname -a"
end

のような簡単なコマンド実行タスクを足すとよい。

希望

Capistranoのバージョンアップでレシピが変わってしまう可能性はあるが、気にしない。Railsのプロジェクトでもデプロイの動作が変わると困るだろうし、そう簡単には変えないんじゃないだろうか。

set :rails, true

とか簡単にRails用のデプロイかどうかを切り替えられたらいいのに。