Capistrano and database.yml
Finally have a good way of working with Capistrano and database.yml. Here's what I did ...
Fundamentals
Generally a Rails application will be run on at least one server and developed on many machines. The database configuration will not be the same on all the machines. In addition the database configuration on the server should be secure.
Remove database.yml from the Repository
Added config/database.yml to projects .gitignore file
Create database.yml.example
This file helps developers connect to there local database. Mine is now
base: &base
user: root
password: '' # only keep in here for dev machines
adapter: mysql
encoding: utf8
# socket: /var/run/mysqld/mysql.sock # ubuntu
socket: /tmp/mysql.sock # leopard
username: #{user}
password: #{password}
development:
database: {appname}_dev
<<: *base
test:
database: {appname}_test
<<: *base
Use Capistrano to create database.yml on the Server
This is based on this blog entry
Here we create a couple of tasks under the :db namespace to create a database configuration using the template in the ERB block. This will be populated with variables in the rest of the deployment recipe, and will prompt for a password for the database. The actual configuration will be created in the #{shared_path}/config/database.yml, so if you can ssh into the server you can look at it.
Anyhow this seems to be working fine on my boxes, and now no database passwords are in the source control tree.
#############################################################
# Database.yml
#############################################################
require 'erb'
before "deploy:setup", :db
after "deploy:update_code", "db:symlink"
namespace :db do
desc "Create database yaml in shared path"
task :default do
db_config = ERB.new <<-EOF
base: &base
adapter: mysql
socket: /var/run/mysqld/mysql.sock
username: #{user}
password: #{password}
development:
database: #{application}_dev
<<: *base
test:
database: #{application}_test
<<: *base
production:
database: #{application}_prod
<<: *base
EOF
run "mkdir -p #{shared_path}/config"
put db_config.result, "#{shared_path}/config/database.yml"
end
desc "Make symlink for database yaml"
task :symlink do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
end
end
Capistrano and Git - Using Same Box for GIT and Deployment
Been a pain getting my git-server and web-server to communicate via ssh as they are the same box. This is partly to do with the fact that my git user is very restricted
I have two users on my server
- Deploy - who is responsible for deploying applications
- Git - who is responsible for Git things
Using capistrano my deploy user has to get the latest src from the git user. Using ssh to do this kept giving me ssh errors.
In the end I had to create a key pair for deploy and put the public key in the git users authorized keys file. Because I could not log in as the git user I had to do this as root.
mv /home/deploy/.ssh/id-rsa.pub /home/git/.ssh/deploy.pub
then backup the authorized keys file and then change permissions so I can write to it.
cd /home/git/.ssh
cp authorized-keys authorized-keys.old
chmod 777 authorized-keys # give all access
cat deploy.pub >> authorized keys # must use double arrow or will overwrite not append!!
chmod 600 authorized-keys # has to have minimal permissions or ssh will complain
Warning
Instructions above are very rough and probably not totally accurate be careful
Update
May well have been able to do this using
set :ssh_options, { :forward_agent => true }
Which forwards ssh keys from the local machine through the web-server to the git-server