Debian Etch - Apache Vhosts, rails and mongrels
One of the ways of serving a Ruby on Rails application is to use Apache to proxy requests to mongrels.
There are a few ways of completing this and we're going to look at one simple solution. Other ways will be looked at in future articles.
Setup
Just a quick note on where we are in the setup. I have my base Debian Etch installed which I updated and secured. I then installed MySQL and Ruby on Rails as per this article.
Once the basics were done I then proceed to install Apache and PHP. Of course, you can leave out the PHP part.
I then created a public_html folder in my home partition and created the correct permissions as shown here.
Rails Application
You can use a pre-existing Rails application or, like me, create a new one from scratch. To do so, move into your public_html folder:
cd /home/demo/public_html
and create a new Ruby on Rails application:
rails railsapp
move into the directory:
cd railsapp
You will notice that the created folders are very similar to the default vhosts layout I describe here
As such, we don't need to create any extra folders as the Apache logs can go into /log and so on.
Mongrels
Let's install the mongrels via ruby gems:
sudo gem install mongrel --include-dependencies
Once done we can move onto the Apache configuration.
Apache modules
Apache will need certain modules to be enabled to allow it to pass the requests to the mongrels.
There are four specific modules that we need. Enable them like so:
sudo a2enmod proxy
sudo a2enmod proxy_balancer
sudo a2enmod proxy_http
sudo a2enmod rewrite
As suggested by the module commands, reload Apache:
sudo /etc/init.d/apache2 force-reload
Virtual host
Now we need to create a new virtual host for the 'railsapp' we created earlier:
sudo nano /etc/apache2/sites-available/domain.com
Obviously use your domain name instead of my example of domain.com
At this stage we are only doing a basic configuration so you can enter the following in the vhosts file:
<VirtualHost *:80>
ServerName domain.com
ServerAlias www.domain.com
DocumentRoot /home/demo/public_html/railsapp/public
RewriteEngine On
<Proxy balancer://mongrelcluster>
BalancerMember http://127.0.0.1:8000
BalancerMember http://127.0.0.1:8001
</Proxy>
# Redirect all non-static requests to Mongrel
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://mongrelcluster%{REQUEST_URI} [P,QSA,L]
ProxyPass / balancer://mongrelcluster/
ProxyPassReverse / balancer://mongrelcluster/
ProxyPreserveHost on
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
# Custom log file locations
ErrorLog /home/demo/public_html/railsapp/log/error.log
CustomLog /home/demo/public_html/railsapp/log/access.log combined
</VirtualHost>
Take each section at a time and you will see that the basics are exactly the same as for a 'normal' vhost configuration.
We have the ServerName, DocumentRoot and Log locations.
Where it differs is the addition of the Proxy settings.
In this example, we will use 2 mongrels running on ports 8000 and 8001 in a balancer named 'mongrelcluster' (call it something more expressive if you have several rails sites - it is also not technically a mongrel cluster but, hey, it's a good name).
The next sections tell Apache to pass the proxy request to the defined balancer. It then sets the permissions on the Proxy so we don't have a dreaded permissions error.
Do note the trailing slash (/) is very important in the ProxyPass settings. Miss them out and it won't work.
Enable
After all of this, don't forget to enable the new vhost:
sudo a2ensite domain.com
And as requested:
sudo /etc/init.d/apache2 reload
If you have a warning regarding mixed ports, you will need to ensure the default vhost has been changed to reflect specific port access as follows:
sudo nano /etc/apache2/sites-available/default
And change the first two lines to read:
NameVirtualHost *:80
<VirtualHost *:80>
...
...
This simply specifies the default HTTP port to listen to rather than a 'wild card' port. Reload Apache and the warning will have gone.
Start your engines
All that's left is to start the two mongrel processes on the ports defined in the vhost. If you are not already in your railsapp directory, move there now:
cd /home/demo/public_html/railsapp
We will start two separate mongrels:
mongrel_rails start -d -e production -p 8000 -P log/mongrel8000.pid
mongrel_rails start -d -e production -p 8001 -P log/mongrel8001.pid
As Debian uses ruby -v1.8.5 as the default you will received a warning:
** Ruby version is not up-to-date; loading cgi_multipart_eof_fix
It is just a warning and, until the aptitude version is updated or you install from source, nothing to be concerned about.
Navigate
Once done, navigate to your domain:
http://www.domain.com
And, if you created a new Ruby on Rails application, you will see this:

Summary
The next article will concentrate on mongrel clusters and ensuring your mongrels survive a reboot.
PickledOnion.


Article Comments:
Andy Croll commented Tue Sep 25 01:16:13 UTC 2007 ago:
Works on Ubuntu!
Also might want to re-mention the location of the default apache vhosts config file when you talk about the ports errors.
PickledOnion commented Tue Sep 25 08:27:24 UTC 2007 ago:
Thanks Andy,
I added an extra line with the path.
PickledOnion.
Long Tran commented Sat Oct 06 16:38:53 UTC 2007 ago:
Thanks for your guide, it works perfect for me.
Matthias commented Fri Jan 04 16:54:23 UTC 2008 ago:
Why do you have a RewriteRule and a ProxyPass in there? Wouldn't either/or suffice?
And, if you use rails caching you should add @RewriteRule ^([^.]+)$ $1.html [QSA] @ to your vhosts file to make sure cached pages are served directly
Craig Ambrose commented Thu May 22 22:13:51 UTC 2008 ago:
Yep, the rewrite rule and proxy pass thing confused me for a while there. It actually means that in the above configuration static files are being served by mongrel, as all files are being passed to the proxy balancer despite the rewrite rules. I suggest the removal of the three lines starting with the world "Proxy" so that the rewrite rules can do the job that they are intended for.