This blog is no longer updated. We have moved to trix.pl/blog. Please update your bookmarks.

302 Permanently Moved!

We're now at trixnews.com. Please update your links. This blog will not be updated anymore.

This blog is no longer updated. We have moved to trix.pl/blog. Please update your bookmarks.

Happy deployment with Capistrano and Rails 1.1

Today is busy as always but I have some info I want to share :)

We have finally migrated to our new co-located server (on 4Gbit/s connection yeah!) and started to prepare it for our incoming app. It's being built on Rails. Our setup is almost typical:
  • Apache2 as a reverse proxy to Lighttpd
  • Lighttpd
  • FCGI listeners running independently from Lighty (with spawner/reaper)
  • Rails (1.1/Edge) app deployed with Capistrano
  • MySQL 5.0
  • etc.
Everything is working almost out of the box. However one thing was tricky to set up: Capistrano deployment and spawner/reaper. There is no spinner i Rails 1.1 (I don't remember when it disappeared) but spawner can respawn fcgi processes if they die.

The problem is that spawner writes pid files into the tmp/pids directory of your current deployed version of app. When you deploy new version, you want to invoke reaper script to restart fcgi listeners, but the pid files are now in the previous release (yes it sounds complicated). We don't want to kill poor spawner and his beloved kids. We want them to live forever! So the trick is to copy pid files from previous release to current one (simple huh?). Below is a custom Capistrano restart task:

desc "Restarts fcgi listeners"
task :restart, :roles => :app do
puts "Restarting fcgi listeners..."
run <<-CMD
cp -r #{previous_release}/tmp/pids #{current_path}/tmp/ &&
#{current_path}/script/process/reaper
CMD
end

One thing that annoyed me (not any more) was the fact fcgi processes listen on wildcard ip address (0.0.0.0) which is not wanted for obvious reasons (we are on a single machine). This is another custom Capistrano task which is invoked only on so-called "cold_deploy":

desc "Starts fcgi listeners"
task :spawn, :roles => :app do
puts "Starting fcgi listeners..."
run "#{current_path}/script/process/spawner -r 5 -s \"/usr/bin/env spawn-fcgi -a 127.0.0.1\""
end

Although on a single machine now, we're prepared for moving application servers to another box if the demand for our services grows beyond expectations (and we hope it will!).