Capistrano (formerly switchtower) is the ‘ruby on rails’ way to deploy your code out onto your fleet of production/test servers. I’ve previously written my own ‘deploy’ script which had similar goals to capistrano, but I’ve only recently tried capistrano itself.

Having now used it, I think it makes a poor design decision. Capistrano runs a “svn co” operation on the deploy host itself. I think it’d be much better to grab a clean set of sources on your local development box, and then rsync/scp that to each deploy host.

The capistrano way is poor for the following reasons. Firstly, since I access my svn respository over ssh I need to have my private key on my deploy host. This is non-optimal for security reasons. I want to keep close tabs on my private keys, and I don’t want it living on a (potentially) compromisable public-facing host. Why not do all the svn stuff locally and keep your private key local?

But it gets worse. Your deployed rails app ends up (by default) being a ‘live’ checked out copy, complete with .svn directories. Additionally, the default rails setup unfortunately exposes the very top level .svn directory in your deployment. This leaks some information: nothing critical, but in security terms any leakage is bad. To find examples, look no further than the list of apps on the RoR site. Examples include 37signals [fixed] and penny arcade and strongspace and iconbuffer [fixed] etc.

Like I say, the information leaked in this way is not too critical. But, if you were into social engineering, knowing the hostname of their internal svn server in addition to login names for several developers could be just the info you need.

What’s the moral to this story? It’s the old lesson of minimal privileges. There’s no real need for the deployment hosts to have ssh access to the svn repository. Nor is there any need to have your deployment version be a ‘live’ checked out version of your source code. I think I will be sticking to a deployment method where I check out locally and rsync to the production hosts …

Update: This method also reveals the contents of some .htaccess files … append .svn/text-base/.htaccess.svn-base to your favourite rails app URL.