capistranoでステージングとか本番環境とか使い分ける
これで動いた!さくらのVPS+github+capistranoでrailsアプリ自動デプロイの設定ファイルを置いておくの続き的エントリ。このさくらのVPSの環境をstagingに変更していく、という内容。
参考
http://d.hatena.ne.jp/ria10/20121211/1355192518
https://github.com/capistrano/capistrano/wiki/2.x-Multistage-Extension
http://railscasts.com/episodes/337-capistrano-recipes?view=asciicast ※有料コンテンツ
設定ファイルとかをstaging対応する
- config/environments/staging.rbを作る
- config/database.ymlにstaging用の設定を入れる
- その他Settingslogicなど、環境依存の記述があるものは全部対応しておく
ちなみにステージングに対応する変数名をstageにしてはいけない。後述のcapistranoのmultistageエクステンションの予約語になっているので。
config/environments/staging.rbの中身は用途に合わせて適当に。僕の場合は本番環境のをコピペして、paperclip使ってたので保存先をs3のステージング用に作ったbucketにしたのと、ログの出力レベルをdebugにしたくらい。
config/deploy/staging.rbを作る
- config/deployディレクトリを掘って、その下に環境ごとの設定ファイルを環境名.rbのテイで置く。
- 前回のエントリ内のdeploy.rbから、環境依存の設定をstaging.rbに移す。
- deploy.rbにmultistageを有効にする設定を入れる
config/deploy/staging.rbはこんな感じになった。
server "staging.example.com", :web, :app, :db, primary: true set :application, "your_staging_app_name" set :user, "your_staging_linux_user" ssh_options[:port] = "your_taging_ssh_port_number" ssh_options[:keys] = [File.join(ENV["HOME"], ".ssh", "your_staging_ssh_key")] set :rails_env, "staging"
あと、multistageエクステンションを使うにはdeploy.rbに以下の記述を入れておく
require 'capistrano/ext/multistage'
環境依存のあるスクリプトをerbにしてうまいこと対応する
前回のエントリのunicorn_init.shのところで
っていうかアプリ名とかルートディレクトリが分散するのがイマイチだなぁ、と思っているので環境変数とかに設定して全部そこから読み込んで設定するようにしたらベターだと思っているし、そのうち挑戦しようと思ってる。しなさそうだけど。
とか言ってたけど、半年の時を経て対応することにした。
で、unicorn_init.shをunicorn_init.erbに変更したら以下のように変える
#!/bin/sh set -e # Feel free to change any of the following variables for your app: TIMEOUT=${TIMEOUT-60} ROOT=<%= deploy_to %> APP_ROOT=$ROOT/current PID=$ROOT/shared/pids/unicorn.pid CMD="cd $APP_ROOT; bundle exec unicorn -D -c $APP_ROOT/config/templates/unicorn.rb -E <%= stage %>" AS_USER=<%= user %> set -u ~snip~
stageという変数があるが、これがcapコマンドを打つときに指定する環境がこの変数に入っている。
あとのdeploy_toとかは、ただのdeploy.rb内でsetした変数。
で、deploy.rbのtask :setup_configの部分を以下のように変える。
task :setup_config, roles: :app do ~snip~ template "unicorn_init.erb", "/tmp/unicorn_init" run "#{sudo} mv /tmp/unicorn_init #{current_path}/config/templates/unicorn_init" run "#{sudo} chmod 775 #{current_path}/config/templates/unicorn_init" ~snip~ end
templateというメソッドがあるけど、これは別途定義しておく。このあたりはRailsCastの知恵。RailsCastはホントちょくちょく役立つ。
config/recipes/base.rb
def template(from, to) erb = File.read(File.expand_path("../../templates/#{from}", __FILE__)) put ERB.new(erb).result(binding), to end
このbase.rbの内容が使えるようにdeploy.rbでloadしておく。ついでに環境の定義もしておく。
set :stages, %(production staging) set :default_stage, "staging" load "config/recipes/base"
set :stagesで環境がproductionとstagingの2種類であることを宣言し、デフォルトがstagingであるようにしておく。この記述によって
$ cap production deploy
みたいに環境を指定したcapコマンドが打てるようになる。
あと、前回はnginxやunicorn絡みの設定ファイルを全部config以下にぶっこんだけど混雑してきたので今回config/templatesを作ってその下に移動しておいた。
スッキリ!