Related tags
Deploying Ruby on Rails on Ubuntu Feisty Fawn via Mongrel Cluster and Apache
Note:
- A quick, down and dirty solution. There are more verbose resources on how to setup Mongrel Cluster and Apache. But this is also specifically tailored for Ubuntu Feisty Fawn.
- After installing mongrel, when executing
./script/server, you will not useWebrickanymore, but insteadmongrelfor development. You can still useWebrickif you want, but there isn't much of a difference.
Plan of Attack
- Install, configure, and test Mongrel Cluster
- Install and test Apache
- Start Mongrel Cluster on boot
Installing Mongrel Cluster
sudo apt-get install ruby1.8-dev sudo gem install -y mongrel mongrel_cluster
Note: If you see the following make sure you select the latest version of mongrel for ruby. In this case option 2.
Select which gem to install for your platform (i486-linux)
1. mongrel 1.0.1 (mswin32)
2. mongrel 1.0.1 (ruby)
3. mongrel 1.0 (mswin32)
4. mongrel 1.0 (ruby)
5. Skip this gem
6. Cancel installation
>
Configuring Mongrel Cluster
Go to your Rails application directory and execute:
mongrel_rails cluster::configure -p 8000 -n 3
This allows mongrel to spawn 3 instance to handle the load. Each instance will open on port 8000, and succeeding. So that is 8000, 8001, and 8002.
Note: The mongrel_rails command has alot of options. Executing mongrel_rails -h will get you more information. All of these options can be changed later.
This will create the a mongrel_cluster configuration file in RAILS_ROOT/config/mongrel_cluster.yml 
Testing Mongrel Cluster
In your Rails application directory, execute:
mongrel_rails cluster::start
Now open up http://localhost:8000/, http://localhost:8001/, and http://localhost:8002/ to ensure that your site is working perfectly fine.
Installing Apache
Enter into the Terminal:
sudo apt-get install apache2 sudo a2enmod proxy_balancer sudo a2enmod proxy_http sudo a2enmod rewrite
We will now create a common rails configuration file. As root open up /etc/apache2/mods-available/rails.conf
, and insert the following:
ServerName railsapp.com
DocumentRoot /var/www/railsapp.com/public
<Directory "/var/www/railsapp.com/public">
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
RewriteEngine On
# Uncomment for rewrite debugging
#RewriteLog logs/railsappapp_rewrite_log
#RewriteLogLevel 9
# Check for maintenance file and redirect all requests
# ( this is for use with Capistrano's disable_web task )
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://mongrel_cluster%{REQUEST_URI} [P,QSA,L]
# Deflate
AddOutputFilterByType DEFLATE text/html text/plain text/css
# ... text/xml application/xml application/xhtml+xml text/javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# Uncomment for deflate debugging
#DeflateFilterNote Input input_info
#DeflateFilterNote Output output_info
#DeflateFilterNote Ratio ratio_info
#LogFormat '"%r" %{output_info}n/%{input_info}n (%{ratio_info}n%%)' deflate
#CustomLog logs/myapp_deflate_log deflate
Now we'll set up the virtual host for our site railsapp.com For the last time as root open up /etc/apache2/sites-available/railsapp
and insert the following:
Listen 8080
<VirtualHost *:8080>
<Location />
SetHandler balancer-manager
Deny from all
Allow from localhost
</Location>
</VirtualHost>
<Proxy balancer://mongrel_cluster>
BalancerMember http://127.0.0.1:8000
BalancerMember http://127.0.0.1:8001
BalancerMember http://127.0.0.1:8002
</Proxy>
<VirtualHost *:80>
Include /etc/apache2/mods-available/rails.conf
ErrorLog /var/log/apache2/rails_errors_log
CustomLog /var/log/apache2/rails combined
</VirtualHost>
The first VirtualHost enables a front end for load balancing, available only to localhost on port 7999.
The second VirtualHost is our rails application. Notice how it is pulling in our default configuration (/etc/apache2/mods-available/rails.conf
). If you want to make changes you can specify it here. Need to specify a ServerName directive? Put it in here.
Lets enable the virtual host
sudo a2ensite railsapp
and restart Apache.
sudo /etc/init.d/apache2 restart
Now pull up your the domain you entered and your Rails application should load!
Note: If you can't seem to access your site, its because the default virtual host has a higher precedence. Execute sudo a2dissite default
. Similarly ensure that you are access your site via the domain you specified in the ServerName directive. In this case railsapp.com
If everything is work, you are on your way to more production based hosting solution.
Start Mongrel Cluster on Boot
Create mongrel_cluster conf directory (/etc/mongrel_cluster).
sudo mkdir /etc/mongrel_cluster
In the Mongrel Cluster gem, there is an init.d script you need to copy.
sudo cp /usr/lib/ruby/gems/1.8/gems/mongrel_cluster-0.2.1/resources/mongrel_cluster/mongrel_cluster /etc/init.d
Now let's make the script executable.
sudo chmod +x /etc/init.d/mongrel_cluster
Now we need to add th init.d script to startup.
On Ubuntu:
sudo update-rc.d mongrel_cluster defaults
On RHEL/CentOS:
/sbin/chkconfig --level 345 mongrel_cluster on
Now create a symbolic link from RAILS_ROOT/config/mongrel_cluster.yml to a file in /etc/mongrel_cluster:
sudo ln -s /path/to/railsapp/config/mongrel_cluster.yml /etc/mongrel_cluster/railsapp
There you have it, you should be good to go!
Comments, bugs, problems, improvements
Have any bug, or problem? Leave a comment please.
Deploying Ruby on Rails on Ubuntu Feisty Fawn via Mongrel and Apache
Note:
- Once again, another quick, down and dirty solution. The guys behind mongrel have even written up how to set it up. This is a more condensed form, and suited for Ubuntu Feisty Fawn
- This is not the best solution for deployment, but it works if you want to do early testing/deployment for clients. An ideal solution would be utilizing
capistranoandmongrel_cluster. - After installing
mongrel, when executing./script/server, you will not useWebrickanymore, but insteadmongrelfor development. You can still useWebrickif you want, but there isn't much of a difference. - This requires the use of RubyGems. If you don't have it installed, see my guide on setting up Rails using RubyGems.
Plan of Attack:
- Install and test Mongrel
- Install and test Apache
- Additional tips
- Mongrel Service
- Let Apache handle Requests for Static Files
- After thoughts
Install Mongrel
Enter into the Terminal:
[block:terminal]
sudo apt-get install ruby1.8-dev build-essential
sudo gem install -y mongrel
[/block]
Note: If you see the following make sure you select the latest version of mongrel for ruby. In this case option 2.
[block:terminal]
Select which gem to install for your platform (i486-linux)
1. mongrel 1.0.1 (mswin32)
2. mongrel 1.0.1 (ruby)
3. mongrel 1.0 (mswin32)
4. mongrel 1.0 (ruby)
5. Skip this gem
6. Cancel installation
>
[/block]
Testing Mongrel
Go into your rails application root directory, and execute:
[block:terminal]
mongrel_rails start -p 8000
[/block]
Open up your webbrowser and go to http://localhost:8000 and your application should load.
Note: mongrel_rails has alot of command line options. Executing mongrel_rails -h will get you more information.
Install Apache
Enter into the Terminal:
[block:terminal]
sudo apt-get install apache2
sudo a2enmod proxy_http
[/block]
You'll need change one file, specifically /etc/apache2/mods-available/proxy.conf
Look for the following line, it should be on line 11:
[block:file]
#Allow from .example.com
[/block]
and replace it with:
[block:file]
Allow from all
[/block]
Now as root, open up /etc/apache2/sites-available/railsapp [image16x16:file].
Enter the following:
[block:file]
<VirtualHost *>
ServerName railsapp.com
ServerAlias www.railsapp.com
ProxyPass / http://www.railsapp.com:8000/
ProxyPassReverse / http://www.railsapp.com:8000/
ProxyPreserveHost on
</VirtualHost>
[/block]
Note: replace railsapp.com and www.railsapp.com with the actual domain/ip you will be using.
Enable the site and restart Apache
[block:terminal]
sudo a2ensite railsapp
sudo /etc/init.d/apache2 restart
[/block]
Testing Apache
Fire up your browser. go to your site. It should be up and running.
Troubleshooting: If you get 403 forbidden, try removing the default site ( [image16x16:terminal] sudo a2dissite default) and change the (www.)railsapp.com setting to localhost. Optionally remove the lines containing ServerName and ServerAlias.
Additional Tips
mongrelwill need to be started up again, when you reboot your machine. We will cover setting it up as a service further down.mongrelcan be given flags to run under a different environment. Perhaps for simple production sites.- If two people try to access the site at the very same time, expect slight delays as only one intsance of
mongrelis running. - From now on
mongrelwill handle all requests. But this is a daft, as Apache can easily handle requests for static files: javascript, stylesheet and images. For solution view further down. - If you want to deploy more than one rails application you'll have to specify a
ServerName, and ensure that mongrel is using different ports
Mongrel Service
There are some tips online on how to setup a mongrel service.
I like the second one by Bojan Mihelac as you can customize the default port, and the environment the mongrel instance is running in.
Here it is reproduced, make sure to install it in /etc/init.d/mongrel [image16x16:file]. Then you can start it by executing /etc/init.d/mongrel start [image16x16:terminal]. Works with start, stop, and restart.
#!/usr/bin/env ruby
#
# mongrel Startup script for Mongrel by Tim Morgan, modified by bmihelac
#
# chkconfig: - 85 15
# description: mongrel manages Mongrel
#
# this would add one mongrels for these two apps on
# ports 8000 and 8001, mephisto would be started in production
apps = [
{:app => 'myapp'},
{:app => 'mephisto', :environment => 'production'},
]
default_port = 8000
default_options = {
:app_dir => '/home/rails',
:environment => 'production'
}
if ['stop', 'restart'].include? ARGV.first
apps.each do |app|
options = default_options.merge(app)
path = File.join options[:app_dir], options[:app]
puts "Stopping #{path}..."
`mongrel_rails stop -c #{path} -P log/mongrel.pid`
end
end
if ['start', 'restart'].include? ARGV.first
apps.each do |app|
options = default_options.merge(app)
path = File.join options[:app_dir], options[:app]
port = options[:port] || default_port
puts "Starting #{options[:app]} on #{port}..."
`mongrel_rails start -d -p #{port} -e #{options[:environment]} -c #{path} -P log/mongrel.pid`
default_port = port + 1
end
end
unless ['start', 'stop', 'restart'].include? ARGV.first
puts "Usage: mongrel {start|stop|restart}"
exit
end
Letting Apache handle Requests for Static Files
Include this into your railsapp file [image16x16:script], inside the <VirtualHost>
[block:file]
ProxyPass /images !
ProxyPass /stylesheets !
#continue with other static files that should be served by apache
Alias /images /path/to/public/images
Alias /stylesheets /path/to/public/stylesheets
#continue with aliases for static content
[/block]
Note: Ensure that the /path/to/public is readable by Apache
After thoughts
Using Mongrel for light sites is alright but it doesn't scale well. Thats why we have mongrel_cluster to the recuse.
