Deployment of Ruby on Rails apps to a production environment has always been a huge pain in the backside. The most common setup seen these days is to run a proxy in front of a cluster of “Mongrels”:, which leaves you with a lot of processes to look after. Not ideal. Recently I got excited about using Jruby and the Glassfish Gem to run apps, but this is something I’m going to come back to at a later date now.

So the new kid on the block is mod_rails (otherwise known as ‘Passenger’) for Apache. So how can this be any easier?

  • Install is a case of installing a gem, running a command, and following the on-screen instructions.
  • Rails now runs within the realm of Apache, so we can start and stop it as if it were one process.
  • This spawns and manages a number of Ruby processes up to a maximum, as demand requires.
  • Restarting the Ruby processes for a specific app is simply a case of modifying a single temp file.
  • Multiple Rails apps can share the pool of Ruby Processes, so no more Mongrels hogging resources that could otherwise be used by other apps.

I run two apps on my Slicehost VPS; this blog, and my training diary. Based on their traffic I was running three and one Mongrels respectively, maybe too many for a 256MB VPS. For Mod_Rails, I decided to follow the recommendation in the documentation of running a maximum of two Ruby workers on the memory I had available. I was running Apache anyway for my public SVN, so the transition was a case of moving my virtualhosts over from Nginx, stopping Nginx and the Mongrels, and restarting Apache. Ludicrously easy.

Some basic benchmarks showed that performance was on a Par with Mongrel, which is certainly pleasing. One small gotcha that I encountered is that the user which the Ruby processes are run under is the same as the owner of environment.rb in your Rails deploy. So check this is the user you want.

Capistrano Restart

If you’re deploying with Capistrano (and why shouldn’t you be?), the add this to your deploy.rb to get your restart rolling:


	namespace :deploy do
	  task :restart do
	    run "cd /path/to/app/current; touch tmp/restart.txt"
	  end
	end

Barring typos, that should be good to go. I look forward to seeing the reception of this amazing improvement in Rails deployment by the community. Shout out in the comments with your thoughts and/or problems.

Update

I had some issues with static files not being served in one of my projects. My solution was to remove the public/.htaccess file that the rails command generates. Hope this helps other’s out.