オレオレ capistrano TIPS: database.yml の設置/unicorn を使う/db:create をリモートから実行する
capistrano を使って rails アプリをデプロイしようとすると、ちょっとしたところでつまづきます。
今日は、最近僕が躓いたこと/調べたことをいくつか書いてみたいと思います。
database.yml を設置する
database.yml にはパスワードなどの扱いに困る情報が載っているので、リポジトリにコミットしたくないファイルのひとつです。
また、開発環境は本番環境などで設定が違うのでどうやってデプロイするか悩みます。
capistrano の wiki ページ では "Managing `database.yml` Securely" と称してこのページが紹介されています。
でも、もう少し調べていくと、実はこのコードは capistrano_database_yml という名前でリリースされています。
というわけで、capistrano_database_yml を使ってみます。
インストール
さっくり gem コマンドで入れます。
$ gem install capistrano_database_yml
capistrano で使うために config/deploy.rb に書き足します。
require 'database_yml/capistrano'
おしまいです。
使ってみる
capistrano_database_yml は二種類の動きをします。
ひとつは deploy:setup のときに #{deploy_to}/shared/config/database.yml を作るというものです。
標準では sqlite を使うダミーの設定を作ってくれます。
もし他の内容にしたい場合は config/deploy/database.yml.erb にファイルを置いておくと、
その内容を #{deploy_to}/shared/config/database.yml に配置してくれます。
もうひとつのアクションはデプロイ終了時に #{deploy_to}/shared/config/database.yml を
config/database.yml として設置してくれます。
あらかじめスケルトンを config/deploy/database.yml.erb に設置しておいて、
deploy:setup を実行した後に必要情報を書き足す。
そして通常の deploy を繰り返す。
という流れで使うことができます。
アプリケーションサーバに unicorn を使う
Web や gist の情報を元に、config/deploy.rb にいろいろ unicorn 用のタスクを書きまくっていたのですが、
capistrano-unicorn というモジュールがあることに気づきました。
インストール
さっくり gem コマンドで入れます。
$ gem install capistrano-unicorn
capistrano で使うために config/deploy.rb に書き足します。
require 'capistrano/unicorn' after 'deploy:start', 'unicorn:start' after 'deploy:stop', 'unicorn:stop'
標準では deploy:restart 用しか見てくれないので、deploy:start と deploy:stop 用のフックを登録しておきます。
データベースを初期化する
何度も実行するものではないのでタスクに登録すべきか迷ったのですが、作業をシンプルにするために
データベース初期化作業を capistrano task にしてみました。
db:drop, db:create, db:migrate, db:seed を次々実行するだけのものです。
namespace :deploy do namespace :db do desc "Create Database" task :create, {:roles => :db, :only => {:primary => true}} do run "cd #{current_path} && bundle exec rake db:create RAILS_ENV=#{rails_env}" end desc "Create Database" task :drop, {:roles => :db, :only => {:primary => true}} do run "cd #{current_path} && bundle exec rake db:drop RAILS_ENV=#{rails_env}" end desc "Load seed data" task :seed, {:roles => :db, :only => {:primary => true}} do run "cd #{current_path} && bundle exec rake db:seed RAILS_ENV=#{rails_env}" end task :init, {:roles => :db, :only => {:primary => true}} do tasks = %w(deploy:update_code deploy:create_symlink db:symlink deploy:db:drop deploy:db:create deploy:migrate deploy:db:seed) agree = Capistrano::CLI.ui.agree("deploy:db:init will DROP your database. Are you sure? (Yes, No)") do |q| q.default = 'No' end transaction do tasks.each do |name| task = top.find_task(name) invoke_task_directly_without_callbacks(task) end end end end end
これを config/deploy.rb に書いておくと、アプリケーションの初回設置が
$ cap deploy:setup $ vi shared/config/database.yml $ cap deploy:db:init $ cap deploy:cold
だけで済むようになる、すぐれもののタスク(自称)です。
よくある内容だと思うので、既に gem パッケージになっているのではないかと思ったのですが、
ブログは見かけても、パッケージ化されたものは見つけられませんでした。
追記(2013/2/16): capistrano-rails-dbinit としてパッケージ化しました。