Capistrano and database.yml

Posted by Andrew Premdas Tue, 27 May 2008 13:23:00 GMT

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

Posted by Andrew Premdas Thu, 22 May 2008 17:36:26 GMT

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

  1. Deploy - who is responsible for deploying applications
  2. 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