There's an echo in my head

日々のメモ。

capistrano_database_ymlでデプロイ時にdatabase.ymlを生成する

capistrano_database_ymlを使うと、デプロイ時にテンプレートからdatabase.ymlを生成することができる。このときcapistrano側からパラメータを与えられるので、multistageと組み合わせると「本番サーバとステージングサーバで同じproduction環境を使いながらDBの接続先が異なる」ということができる。*1

.gitignore:

config/database.yml

Gemfile:

group :development do
  gem 'capistrano_database_yml',  :require => false
end

config/deploy.rb:

require "capistrano/ext/multistage"
require "database_yml/capistrano"

set :stages, %w(production staging)
set :default_stage, "staging"

config/deploy/database.yml.erb:

development:
  :
test:
  :
production:
  adapter: mysql2
  encoding: utf8
  database: myapp_production
  pool: 5
  username: root
  password:
  host: <%= database_host %>
  port: <%= database_port %>

config/deploy/production.rb:

set :database_host, "production.db.example.com"
set :database_port, "3306"

config/deploy/staging.rb:

set :database_host, "staging.db.example.com"
set :database_port, "3306"

設定は以上。

cap staging deploy:setupをすると、database.yml.erbをもとにshared/config/database.ymlが作成される。

普段の開発環境でdatabase.ymlを生成するには次のようなスクリプトを実行する。

bin/init:

#!/usr/bin/env ruby
require "erb"

puts "Generating config/database.yml"

path_to_erb = File.expand_path("../../config/deploy/database.yml.erb", __FILE__)
path_to_yml = File.expand_path("../../config/database.yml", __FILE__)

def database_config
  database_host = "dummy.database.host"
  database_port = 3306
  binding
end

erb = ERB.new(File.read(path_to_erb))
File.open(path_to_yml, "w") { |f| f.puts erb.result(database_config) }

参考

*1:ごっちゃにはなり易いので気をつける必要はある。

このブログに出てくるコードスニペッツは、引用あるいは断りがない限りMITライセンスです。