desc "Setup Database Configuration"
task :database_configuration_setup do
# generate database configuration
database_configuration = render :template => <<-EOF
# Deployment database.yml
login: &login
adapter: #{database}
username: #{database_username}
development:
database: #{application}_development
<<: *login
test:
database: #{application}_test
<<: *login
production:
database: #{application}_production
<<: *login
EOF
# put database configuration in shared config dir
put database_configuration, "#{deploy_to}/#{shared_dir}/config/database.yml"
end
This of course means I use variables for #{database} as the adapter,
and #{database_username} and so on -- that way it builds it for me.
I call this task in after_setup so that if I ever make changes to the
setup/configuration, I can just run setup on the box (or a new box) to
set it all up for me.
I used to keep the deployment specific database.yml and copy it over,
but this way I can use the variables and build it dynamically.
hope this helps, cheers,
--
Charles Brian Quinn
self-promotion: www.seebq.com
highgroove studios: www.highgroove.com
slingshot hosting: www.slingshothosting.com
desc "Tasks to execute after code update"
task :after_update_code, :roles => [:app, :db] do
# relink shared deployment database configuration
run "ln -nfs #{deploy_to}/#{shared_dir}/config/database.yml
#{release_path}/config/database.yml"
# ....
# ....
end
Assuming you agree with this logic ;), you can run this from within
your rails app (when you first setup):
svn move config/database.yml config/database.example
svn propset svn:ignore "database.yml" config/
# at this point, edit your database.example so it has NO
passwords (and maybe even no logins for production?)
# if you already checked in a password, it will stay in SVN even
if you change the current file.
# at that point you should create a new password for your
production db.
svn commit -m 'Moving database.yml to database.example to provide
a template for anyone who checks out
the code, and ignore 'database.yml' in the future'
svn up
at this point your svn will be fine, but none of your applications
will work! For each developer, they can have their own database.yml
with their dev information. For your production servers, and assuming
you are using capistrano, you can add this to your capistrano.rake file
(or to your own recipe file) to do the following:
desc "create a shared/resources directory for common, non-svn files
(like database.yml)"
task :after_setup, :roles => [:app, :db, :web] do
run <<-CMD
mkdir -p -m 777 #{shared_path}/resources &&
mkdir -p -m 777 #{shared_db} &&
touch #{shared_path}/resources/database.yml
chmod 600 #{shared_path}/resources/database.yml
CMD
end
desc "create a symlink for the database.yml file for the current
project (since it isn't in source control)"
task :after_update_code, :roles => [:app, :db, :web] do
run <<-CMD
ln -nfs #{shared_path}/resources/database.yml
#{release_path}/config/database.yml
CMD
end
and then put the information you need for your production environment
in the #{shared_path}/resources/database.yml
It sounds complicated to setup, but once it is you won't have to touch
it or even think about it again until you rotate a production password.
If more than 1 person works on the project, this can also make
development easier.
Hope that wasn't *too* complicated!
Adam
desc "Create config/database.yml in shared"
task :after_setup, :roles => [:app] do
# prompt user for password
set :db_password, Capistrano::CLI.password_prompt("DB password:")
database_configuration = render :template => <<-EOF
---
production:
adapter: mysql
database: myapp_production
host: gecko.fcit.usf.edu
username: myapp_user
password: <%= db_password %>
EOF
run "mkdir -p #{shared_path}/config"
put database_configuration, "#{shared_path}/config/database.yml"
end
One thing I've been meaning to do--change this task to read in the
other settings from my local database.yml (assuming I can do that, I
haven't experimented with where cap is running from) and prompt for the
password only if its blank there, which is exactly how my db.yml is set
up. Seems DRYer to me to do it that way.
Hell, if that doesnt work, I could probably just set it up to copy over
the template database.yml and insert the password into that. Hrmm, that
might even be a better idea.