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
- サーバが1つだけならroleは1つでよい。
- 1行目のset :userも指定しなくてもよい。
- ユーザ名は、roleのホスト名の前に@を付けて書くことができる。
- @がなければset :userで指定したユーザ名がデフォルトになる。
- でなければ現在のログインユーザ名がデフォルトになる。
- taskに:rolesを指定すると、特定のサーバだけ操作できる。
- setは変数を設定している。タスクで参照できる。
- set(:time) { Time.now } のようにブロックを設定して遅延評価できる。
- リモートの標準出力を受け取るstream機能がある。ログのtailを表示したりできる。
- stream "tail -f yourapp.log"
- https://github.com/capistrano/capistrano/wiki/2.x-DSL-Action-Inspection-Stream
- ドキュメント
- Home · capistrano/capistrano Wiki · GitHub
- アクション https://github.com/capistrano/capistrano/wiki/2.x-DSL-Documentation-Action-Module
- runでコマンドを実行する以外にも、ファイルの送受信put、deleteなどができる。
- 設定 https://github.com/capistrano/capistrano/wiki/2.x-DSL-Documentation-Configuration-Module
- 上で使ったset, task, role以外にもいくつかある。
- 変数 https://github.com/capistrano/capistrano/wiki/2.x-Significant-Configuration-Variables
- 付属のレシピが使っている変数。
- Home · capistrano/capistrano Wiki · GitHub
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' の行でベースのレシピが読み込まれる。
- capistrano-2.5.18/lib/capistrano/recipes/deploy.rb
このソースを見ながらRailsに依存する部分を修正をした。デフォルトだと、deployタスクは下のように呼ばれる。
- default …… 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用のデプロイかどうかを切り替えられたらいいのに。