Mongrel, Apache and Rails on Debian Sarge

to set up the great Mongrel web server including a recent version of Ruby and everything else needed to run your Rails applications in a combined Mongrel/Apache load balanced setup on a rock solid and easy-to-maintain Debian Sarge server ?

If the answer is yes, this one is for you.

Not that I don’t like gem, but on production systems I prefer to have as less package mangement systems as possible ;-)

So the goal is to set up such a server, without doing a single gem install or ruby setup.rb. We’ll need to install rubygems itself, though, since Mongrel depends on it. But as there’s already a debian package for this, there’s nothing to worry about.

The first repository will give you access to the Ruby 1.8.4 and Mongrel debian packages. The second repo is for RubyGems, which Mongrel depends upon. Thanks to the Debian/Ruby Extras team I didn’t need to package this myself :-). Don’t be afraid of the experimental, we’ll take care that your server stays stable now:

Add this to /etc/apt/preferences to give packages from the experimental repository a low priority:

Package: *
Pin: release a=experimental
Pin-Priority: 100

And finally, tell apt that you want to have a stable system by adding this to /etc/apt/apt.conf:

APT::Default-Release "stable";

If one of the latter two files doesn’t exist, just create it.

Now, type

apt-get update
apt-get install mongrel

This should pull in Ruby 1.8.4 and some other dependencies automatically.

If you’re not running Apache 2.2 (which usually is the case on Sarge systems), you should apt-get install pen, too. This will give you the Pen load balancer we’ll use to distribute traffic between multiple Mongrel instances. With Apache 2.2, mod_proxy can take over Pen’s job, see here for details on this.

Configuration

Mongrel

To give Mongrel a test drive, you should have a Rails application installed somewhere on your server. Each application gets it’s own config file in /etc/mongrel/sites-enabled/. The name of the config file will be used in start, restart and stop commands, so be sure to choose something meaningful.

Here’s an example config, comments included:

# RAILS_ROOT of your application
dir=/home/webapps/your_application/current
# port the first mongrel instance should listen to, additional instances will use ports above this
port=8100
# number of mongrel instances
servers=3
# port pen will listen on
proxy_port=8001

By default, Mongrel will be run under the www-data account, just like Apache, too. This can however be overridden by setting the USER variable in /etc/default/mongrel to some other account on your server. Just make sure the user has write access to the tmp and log directories of your app. Write access to public is needed for Rails page caching. I usually simply set the owner of these directories to www-data:

chown -R www-data tmp log public

If you’re using capistrano for deployment, you have to repeat this for tmp and public after each deployment (log is symlinked from shared and therefore will keep it’s permissions during deployments). A custom after_update_code task might look like this:
task :after_update_code do
sudo "chown -R www-data #{release_path}/public #{release_path}/tmp"
end

Apache

Now we tell Apache to forward requests for your app to the load balancer. You’ll need mod_proxy and mod_rewrite for this. a2enmod {proxy|rewrite} can be used to enable the modules, in case they aren’t yet.

For the sake of spam checking any data you submit, including your IP address, will be transferred to the US based Akismet web service (akismet.com). If that's not acceptable for you, you can also reach me by other means.