Ubuntu Hardy - Apache, Rails and mongrels

Following from the mongrel and mongrel cluster article, we can now look at creating and configuring Apache to proxy to a mongrel cluster so we can serve our Ruby on Rails application.


Prerequisites

To get the most out of this article you need to have a couple of things preinstalled:

Firstly, you need Apache installed (see this article) - if you don't require PHP then please feel free to leave that section out.

Secondly, you will need to have installed mongrels as per the mongrel and mongrel cluster article link above.

Rails application

To start with, we will need a basic Ruby on Rails application. Move into your public_html folder (create one if you do not have one already):

cd ~/public_html

Then create a Rails application. We'll use the default sqlite database for this example:

rails railsapp

Apache modules

Apache will need the proxy and rewrite modules enabled.

Depending on your Apache install you may need to issue all the following commands:

sudo a2enmod proxy
sudo a2enmod proxy_balancer
sudo a2enmod proxy_http
sudo a2enmod rewrite

Once done, reload Apache:

sudo /etc/init.d/apache2 force-reload

What's the plan, Stan?

Well, for our simple application we're going to create a mongrel cluster consisting of 3 mongrels running on port 5000 in production mode. We'll also add a symlink so the cluster will restart if the Slice is rebooted at any point.

Then we can create an Apache virtual host to serve the Ruby on Rails application.

Mongrel Cluster

I won't go into the details of explaining what the commands are in this section. Please refer to the main mongrel and mongrel cluster article for that.

Ensure you are in the rails folder:

cd ~/public_html/railsapp

Then create a mongrel cluster file as such:

mongrel_rails cluster::configure -e production -p 5000 -N 3 -c /home/demo/public_html/railsapp -a 127.0.0.1

It's always a good idea to check the created file (config/mongrel_cluster.yml):

cwd: /home/demo/public_html/railsapp
log_file: log/mongrel.log
port: "5000"
environment: production
address: 127.0.0.1
pid_file: tmp/pids/mongrel.pid
servers: 3

Looks good.

Now create a symlink to the /etc/mongrel_cluster folder. This ensures the cluster is restarted on a reboot:

sudo ln -s /home/demo/public_html/railsapp/config/mongrel_cluster.yml /etc/mongrel_cluster/railsapp.yml

Now all we need to do is start the cluster:

mongrel_cluster_ctl start

Done.

Apache Virtual Host

Now we can create the virtual host:

sudo nano /etc/apache2/sites-available/domain.com

he following will suffice for a basic application:

<VirtualHost *:80>
  ServerName domain.com
  ServerAlias www.domain.com

  DocumentRoot /home/demo/public_html/railsapp/public

  RewriteEngine On

  <Proxy balancer://mongrel1>
    BalancerMember http://127.0.0.1:5000
    BalancerMember http://127.0.0.1:5001
    BalancerMember http://127.0.0.1:5002
  </Proxy>

  # Redirect all non-static requests to thin
  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
  RewriteRule ^/(.*)$ balancer://mongrel1%{REQUEST_URI} [P,QSA,L]

  ProxyPass / balancer://mongrel1/
  ProxyPassReverse / balancer://mongrel1/
  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>

Nice and simple and, as you may have noticed, is the pretty much the same as the Apache vhost we created when using the 'thin' web server (see this article).

There is a good reason they are the same - all they are doing is proxying rails requests to the 3rd party server. In this case, the requests are proxied to the mongrel cluster.

Enable

Now we must enable the vhost:

sudo a2ensite domain.com

Reload Apache:

sudo /etc/init.d/apache2 reload

If you get any port and NameVirtualHost errors then please read the Apache Virtual Host article which will take you through setting up said details.

Navigate

All that's left is to navigate to your domain:

http://www.domain.com

Where you will be greeted with the rails welcome page.

Summary

Setting up a virtual host to proxy to a mongrel cluster is fairly simple.

Although setting up and configuring mongrel, especially if you want them restart on a reboot, can be a bit complicated, once done it is a quick and powerful method in serving your Ruby on Rails application.

PickledOnion

Article Comments:

chris commented Wed May 14 01:41:06 UTC 2008:

Note that build-essential is required

sudo apt-get install build-essential

PickledOnion commented Wed May 14 09:07:32 UTC 2008:

Hi Chris,

You are quite right - build-essential is required and is part of the basic Slice setup:

slice setup - page 2

PickledOnion

Andy commented Sat Jul 26 18:56:16 UTC 2008:

When I tried to use the example virtualhost config, "apache2 reload" balked with "mixing * and non-* ports with a NamedVirtualHost is not supported"

I may have missed a step in the apache2 setup, but I got around this by changing the asterisk at the top "VirtualHost *:80" to the actual ip of my slice, eg: "VirtualHost 1.2.3.4:80". Then it all worked.

DJ commented Tue Dec 02 10:38:02 UTC 2008:

I am getting this error->

[Tue Dec 02 00:47:15 2008] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8000 (127.0.0.1) failed [Tue Dec 02 00:47:15 2008] [error] approxyconnect_backend disabling worker for (127.0.0.1) [Tue Dec 02 00:47:15 2008] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8001 (127.0.0.1) failed [Tue Dec 02 00:47:15 2008] [error] approxyconnect_backend disabling worker for (127.0.0.1) [Tue Dec 02 00:47:15 2008] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8002 (127.0.0.1) failed [Tue Dec 02 00:47:15 2008] [error] approxyconnect_backend disabling worker for (127.0.0.1) [Tue Dec 02 00:47:20 2008] [error] proxy: BALANCER: (balancer://mongrel_cluster). All workers are in error state

Adam commented Thu Jan 08 17:07:07 UTC 2009:

Hello,

I used the tutorial above. Thx for it, it's the first one which works for me. But I still have a problem. I can't protect the domain with .htaccess.I changed the conf file as follows:

<virtualhost> ServerName domain.de ServerAlias www.domain.de

DocumentRoot /root/public_html/railsapp/public

<directory /> Options FollowSymLinks AllowOverride AuthConfig Order allow,deny Allow from all </directory>

RewriteEngine On

<proxy /> BalancerMember http://127.0.0.1:5000 BalancerMember http://127.0.0.1:5001 BalancerMember http://127.0.0.1:5002 </proxy>

# Redirect all non-static requests to thin RewriteCond %{DOCUMENTROOT}/%{REQUESTFILENAME} !-f RewriteRule ^/(.*)$ balancer://mongrel1%{REQUEST_URI} [P,QSA,L]

ProxyPass / balancer://mongrel1/ ProxyPassReverse / balancer://mongrel1/ ProxyPreserveHost on

<proxy> Order deny,allow Allow from all </proxy>

# Custom log file locations ErrorLog /root/public_html/railsapp/log/error.log CustomLog /root/public_html/railsapp/log/access.log combined

</virtualhost>

The .htaccess is stored in /root/public_html/railsapp/public and has the following settings:

AuthType Basic AuthUserFile /root/htaccess/.passwd AuthName "geschuetzer Bereich"

order deny,allow allow from all require valid-user

But the domain is still not protected. Do you know why I can't activate the AuthConfig??

Thx

don commented Wed Mar 25 00:03:09 UTC 2009:

I have followed this to the t and I do not have a /etc/mongrel_clusters/ folder and hence it does not work!

I have installed mongrel_cluster several times and still nothing it the /etc/ folder any ideas?

D

kenny commented Wed Apr 14 08:55:24 UTC 2010:

Hi, Thank you , I have completed , but the local access , external netword can not access why ?

Want to comment?


(not made public)

(optional)

(use plain text or Markdown syntax)