Capistrano 3 で secrets.yml をどう配置するか
2015/06/16
約1年10ヶ月ぶりの「Rails Tips」です。
今回は、Capistrano 3 で Rails アプリケーションをデプロイする時に、secrets.yml
をどう扱うか、というお話しをします。
secrets.yml
は Rails 4.1 で導入されたファイルです。その名の通り、秘密の情報を記録するためのファイルです。Facebook の API Key などを記録してもいいのですが、今回の話は secret_key_base
に限定します。
このファイルの扱いが面倒なのは、次の3つの理由によります:
- 秘密の情報なので Git リポジトリにコミットできない。
- デプロイ対象のすべてのサーバーに同一内容のファイルを配置しなければならない。
- (セッションが切れてしまうので)運用中は原則として内容を変更できない。
早速ですが、私のやり方を紹介します。lib/capistrano/tasks
ディレクトリ(なければ作ってください)に新規ファイル secrets_yml.rake
を次のような内容で作成してください。
namespace :deploy do
desc "Upload secrets.yml to the shared/config directory."
task :secrets_yml do
unless File.exist?('tmp/secrets.yml')
secrets = { fetch(:stage).to_s =>
{ 'secret_key_base' => SecureRandom.hex(64) } }
File.open('tmp/secrets.yml', 'w') do |f|
f.write secrets.to_yaml
end
end
on roles(:app) do
unless test "[ -f #{shared_path}/config/secrets.yml ]"
unless test "[ -d #{shared_path}/config ]"
execute "/bin/mkdir -p #{shared_path}/config/"
end
upload! "tmp/secrets.yml", "#{shared_path}/config/secrets.yml"
end
end
end
end
そして、config/deploy.rb
に次の記述を加えます。
set :linked_files, %w{ config/secrets.yml }
こうすれば、Capistrano が shared/config/secrets.yml
に対するシンボリックリンクを current/config
ディレクトリに作成してくれます。
ちなみに、私の config/deploy.rb
では次のような記述になっています。
set :linked_files, %w{ config/database.yml config/secrets.yml }
データベース接続設定のファイル database.yml
もシンボリックリンクされる設定です。
準備作業は以上です。デプロイ先に shared
ディレクトリが存在する状態で、次のコマンドを実行すれば、デプロイ対象のすべてのサーバーに対して同一の secrets.yml
が配置されます。
$ bin/cap production deploy:secrets_yml
うまく配置できたら、ローカルの tmp
ディレクトリにある secrets.yml
は削除しておきましょう。
ところで、デプロイ対象のサーバーを新設する時には注意が必要です。そのまま上記のコマンドを実行すると、既存のサーバー群と新設のサーバー群との間で secrets.yml
の内容が異なってしまいます。secret_key_base
の値はセッションの暗号化に使われるので、すべてのサーバーで共通していなければなりません。
サーバーを新設するときは、既存の secrets.yml
を tmp
ディレクトリにダウンロードしてからデプロイを行ってください。
なお、環境変数 SECRET_KEY_BASE
を使ったデプロイ方法もネットで紹介されていますが、かえってややこしくなるように私には思えます。