Thinking in GIS
a blog about GIS from a urban geogeek living at the countryside
Ruby on Rails applications with Mongrel cluster and Apache url rewriting on Ubuntu
Posted: November 08, 2007Categories: devs, Apache, Ruby on Rails, Ubuntu
Feedback: View Comments
This is the workflow I followed for setting up my Ubuntu (Ubuntu 7.04 - the Feisty Fawn, but should work without problems also for the latest Ubuntu 7.10 - Gutsy Gibbon ) development machine for serving Rails application with Mongrel clusters and Apache.
Install Ruby, gems and Ruby on Rails
# install ruby
sudo apt-get install ruby ri rdoc libmysql-ruby
# download rubygems
sudo wget http://rubyforge.org/frs/download.php/20989/rubygems-0.9.4.tgz
# tar rubygems
tar -xvzf rubygems-0.9.4.tgz
# ruby setup.rb rubygems script
cd rubygems-0.9.4
sudo ruby setup.rb
# download and install Ruby on Rails framework
sudo gem install rails --include-dependencies
Install Apache 2.2 and enable the needed modules (url rewriting, proxy, proxy_balancer e proxy_http)
# install Apache 2.2
sudo apt-get install apache2
# first way to enable modules in apache
cd /etc/apache2/mods-enabled/
sudo ln -s ../mods-available/rewrite.load rewrite.load
sudo ln -s ../mods-available/proxy.load proxy.load
sudo ln -s ../mods-available/proxy_balancer.load proxy_balancer.load
sudo ln -s ../mods-available/proxy_http.load proxy_http.load
# second way to enable modules in apache
sudo a2enmod rewrite
sudo a2enmod proxy
sudo a2enmod proxy_balancer
sudo a2enmod proxy_http
Install Mongrel, create a Mongrel user, create the mongrel cluster
# Install Mongrel
sudo gem install daemons gem_plugin mongrel mongrel_cluster --include-dependencies
# create the mongrel user
sudo /usr/sbin/adduser -r mongrel
# create the mongrel cluster
sudo mongrel_rails cluster::configure -e production -p 3010 -N 2 -c /home/corti/Documents/ror/myapp -a 127.0.0.1 --user mongrel --group mongrel
In the last line we use the mongrel_rails command to create a mongrel cluster with 2 processes (-N option) responding at the http://127.0.0.1 (-a option) on ports 3010, 3011 (-p option) serving a rail application at the path /home/corti/Documents/ror/myapp (-c option) that will be started from the mongrel user (--user and --group options).
After creating the mongrel cluster, you will have the file mongrel_cluster.yml created in the config directory of your Ruby application, and it should reflects all the parameters you have used with the mongrel_rails command:
user: mongrel
cwd: /home/corti/Documents/ror/myapp
log_file: log/mongrel.log
port: "3010"
environment: production
group: mongrel
address: 127.0.0.1
pid_file: tmp/pids/mongrel.pid
servers: 2
the log directory of the ruby application has to be writable by the mongrel user, and then you can start your clusters:
# make log and temp directories writable from mongrel user
sudo chown -R mongrel:mongrel /home/corti/Documents/ror/myapp/tmp
sudo chown -R mongrel:mongrel /home/corti/Documents/ror/myapp/log
# start mongrel clusters
sudo mongrel_rails cluster::start
you can now test if your cluster is working, you just need to type in the browser the following urls (assuming you have followed the steps in a identical way:
http://localhost:3010 http://localhost:3011
Now we need to make sure that mongrel clusters are started on boot. We can do like this:
# create a mongrel_cluster directory in /etc directory
sudo mkdir /etc/mongrel_cluster
# create a link to the mongrel_cluster.yml in the /etc/mongrel_cluster folder
# (name the link as your application, so many ruby application's mongrel cluster file
# will be linked there and they will be booted at startup
sudo ln -s /var/www/apps/testapp/config/mongrel_cluster.yml /etc/mongrel_cluster/myapp.yml
# copy (or link) the mongrel_cluster init script (you will find it in your mongrel installation path)
# to the /etc/init.d folder
sudo cp /path/to/mongrel_cluster_gem/resources/mongrel_cluster /etc/init.d/
# make the script executable
sudo chmod +x /etc/init.d/mongrel_cluster
# install as a service
cd /etc/init.d/
sudo /usr/sbin/update-rc.d -f mongrel_cluster defaults
Add your app as a host in hosts.file (sudo gedit /etc/hosts):
127.0.0.1 localhost
127.0.0.1 myapp
Configure Apache configuration file (sudo gedit /etc/apache2/sites-available/default). Note that you need the Proxy section as far on Ubuntu this is not allowed by default and without it you would receive this error (check in Apache log file): "proxy: No protocol handler was valid for the URL /. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration"
NameVirtualHost *:80
#we need this as on Ubuntu by default Proxy is not allowed
Order allow,deny
Allow from all
#Proxy balancer section (create one for each ruby app cluster)
BalancerMember http://myapp:3010
BalancerMember http://myapp:3011
#Virtual host section (create one for each ruby app you need to publish)
ServerName myapp
DocumentRoot /home/corti/Documents/ror/myapp/public/
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
#log files
ErrorLog /var/log/apache2/myapp_error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/myapp_access.log combined
#Rewrite stuff
RewriteEngine On
# Check for maintenance file and redirect all requests
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [L]
# Rewrite index to check for static
RewriteRule ^/$ /index.html [QSA]
# Rewrite to check for Rails cached page
RewriteRule ^([^.]+)$ $1.html [QSA]
# Redirect all non-static requests to cluster
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://myapp_cluster%{REQUEST_URI} [P,QSA,L]
Restart Apache:
sudo /etc/init.d/apache2 restart
Check if your ruby application is now working served by Apache rewriting the url to the cluster:
http://myapp
References: blog.codahale.com kpumuk.info