4.2. Common ConfigurationsNow that you can see how easily Mongrel can be configured, let's see what people are doing with it. Most of the configuration options will change from defaults because you want to run Mongrel in a cluster or in a production environment where you want to sit it behind a static HTTP server like Apache. 4.2.1. Mongrel Standalone
As a real HTTP server, Mongrel will work just fine as a front-
4.2.2. A Pack of Mongrels (mongrel_cluster)
Depending on what kind of Web application you're running and how much traffic you expect, you might want to have multiple Mongrel processes running in a cluster. If you are accustomed to running multiple FCGI processes, then you will want to run a cluster of Mongrel processes (a "cluster" in this case does not mean you need separate machines, just separate processes running on a single machine). To help figure out how many Mongrels you'll need, you should read "How Many Mongrels" (http://rubyforge.org/pipermail/mongrel-users/2006-May/000200.html). If you need at least two, then you'll want to run a cluster. You do this with the mongrel_cluster gem, written by Bradley Taylor from RailsMachine. Detailed instructions for setup and use are available on the Mongrel Web site (http://mongrel.
4.2.3. Mongrel Behind a "Static" Web Server
A common configuration for running a Rails application these days is to have a fast, compiled Web server like Apache field incoming
4.2.3.1. Static Server Options
Apache has been frowned upon by many Rails developers because of its flaky support for FastCGI, which was previously the least-horrible way to run a Rails application. FastCGI was pretty
4.2.3.2. What about LightTPD?
When FastCGI was the best option out there, LightTPD (aka Lighty) was
|
4.3. Hit the Ground Running: Example ConfigurationsIn this section we will cover two example configurations that will let you run a cluster of Mongrels behind a fast static Web server. 4.3.1. Apache Has Returned: Apache + mod_proxy_balancer + Mongrel
With the
Apache is a
4.3.1.1. Install Apache 2.2
We're going to download and compile Apache from source. If you have trouble getting Apache to run and compile, you will find many
$ curl -O http://www.ip97.com/apache.org/httpd/httpd-2.2.3.tar.gz $ tar zxvf httpd-2.2.3.tar.gz $ cd httpd-2.2.3 $ ./configure \ --enable-proxy \ --enable-proxy-balancer \ --enable-proxy-http \ --enable-rewrite \ --enable-cache \ --enable-headers \ --enable-ssl $ make $ sudo make install $ sudo /usr/local/apache2/bin/apachectl -k start 4.3.1.2. Set Up Your Mongrel Cluster ConfigWe're going to use a simple cluster of two Mongrels, using mongrel_cluster . Here we simply run the cluster::configure command, then start the cluster.
$ cd ~/code/examples/duck $ mongrel_rails cluster::configure -p 3000 -e production -a 127.0.0.1 -N 3 Writing configuration file to config/mongrel_cluster.yml. $ mongrel_rails cluster::start Starting 3 Mongrel servers... 4.3.1.3. Modify the Default Apache ConfigWe will add one line to the default Apache config http.conf (look in /usr/local/apache2/conf )
# Include an external config for our examples Include /usr/local/apache2/conf/duck.conf For the purpose of this example, we're going to put all new configuration details in a single file called duck.conf in the default Apache configuration directory ( /usr/local/apache2/conf/ ).
NameVirtualHost *:80
# Setup the cluster
<Proxy balancer://duck_cluster>
BalancerMember http://127.0.0.1:3000
BalancerMember http://127.0.0.1:3001
BalancerMember http://127.0.0.1:3002
</Proxy>
# Setup the VirtualHost for your Rails application
<VirtualHost *:80>
ServerAdmin duck@example.com
ServerName localhost
ServerAlias localhost
DocumentRoot /Users/matt/code/examples/duck/public
<Directory '/Users/matt/code/examples/duck/public'>
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
ProxyPass / balancer://duck_cluster/
ProxyPassReverse / balancer://duck_cluster/
# Setup your Rewrite rules here
RewriteEngine On
# Rewrite index to check for static
RewriteRule ^/$ /index.html [QSA]
# Send all requests that are not found as existing files to the cluster
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} ! -f
RewriteRule ^/(.*)$ balancer://duck_cluster%{REQUEST_URI} [P,QSA,L]
# Error logs
ErrorLog /Users/matt/code/examples/duck/log/apache_error_log
CustomLog /Users/matt/code/examples/duck/log/apache_access_log combined
</VirtualHost>
4.3.2. From Russia, with Love: Nginx [2]
One of the chieftains of the Rails deployment world, Ezra Zygmunowicz, found a Russian Web server that happens to be mature, feature-complete, and fast called Nginx (think "Engine X"). It has a low memory footprint, and the proxying is faster than Apache's mod_proxy_balancer . He worked with some fellow developers and managed to get the configuration worked out. There is a wiki for Nginx English Documentation (http://wiki.codemongers.com/Nginx) to help guide you through any changes you'd like to make for your own setup. You'll want to set up mongrel_cluster the same way we did in the previous section for Apache. 4.3.2.1. Install NginxInstalling Nginx is straightforward. This will install it into /usr/local/nginx.
$ curl -O http://sysoev.ru/nginx/nginx-0.4.0.tar.gz $ tar zxvf nginx-0.4.0.tar.gz $ cd nginx-0.4.0 $ ./configure --sbin-path=/usr/local/sbin --with-http_ssl_module $ make $ sudo make install 4.3.2.2. Set Up the Nginx ConfigNow we can use a nice configuration that Ezra has honed to a sharp edge. In this example we are saving this in our Rails application's config directory as nginx.conf .
# User and group to run as
user matt matt;
# Number of nginx workers
worker_processes 2;
# pid of nginx master process
pid logs/nginx.pid;
# Number of worker connections. 1024 is a good default
events {
worker_connections 1024;
}
# start the http module where we config http access.
http {
# Pull in mime-types. You can break out your config
# into as many includes as you want to make it cleaner
include conf/mime.types;
# set a default type for the rare situation that
# nothing matches from the mime-type include
default_type application/octet-stream;
# configure log format
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "http_x_forwarded_for" ';
# main access log
access_log logs/access.log main;
# main error log
error_log logs/error.log debug;
# OSX does not support sendfile.
# Uncomment this if you're on linux or bsd
#sendfile on;
# These are good default values.
tcp_nopush on;
keepalive_timeout 65;
tcp_nodelay on;
# this is where you define your mongrel clusters.
# you need one of these blocks for each cluster
# and each one needs its own name to refer to it later.
upstream mongrel {
server 127.0.0.1:3001;
server 127.0.0.1:3002;
server 127.0.0.1:3003;
}
# output compression saves bandwidth
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_types text/plain text/html text/css text/js;
# the server directive is nginx's virtual host directive.
server {
# port to listen on. Can also be set to an IP:PORT
listen 80;
# sets the domain[s] that this vhost server requests for
#server_name example.com www.example.com;
# Set the max size for file uploads to 50Mb
client_max_body_size 50M;
# doc root
root /Users/matt/code/examples/duck/public;
# vhost specific access log
access_log logs/host.access.log main;
# If you have a 'maintenance.html' in your doc root, all
# requests will be forwarded to that automatically.
# This is part of Capistrano's 'disable_web' task.
if (-f $document_root/maintenance.html){
rewrite ^(.*)$ /maintenance.html last;
break;
}
location / {
# needed to forward user's IP address to rails
proxy_set_header X-Real-IP $remote_addr;
# needed for HTTPS
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect false;
# Basic Caching
# Add /index.html to the request and check to see if that
# file exists. If it does, continue to the next config.
if (-f $request_filename/index.html) {
rewrite (.*) /index.html break;
}
# Rails Caching rules
# Add .html to the end of the request, then check for a file
# with that name. If the file exists, continue to the next
# config. Otherwise set the headers and proxy the request to
# the mongrel cluster.
if (-f $request_filename.html) {
rewrite (.*) .html break;
}
if (! -f $request_filename) {
proxy_pass http://mongrel;
break;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
You can test the configuration like so:
$ sudo /usr/local/sbin/nginx -t -c config/nginx.conf Starting is the same as the testing command, without the -t option.
$ cd ~/code/examples/duck $ sudo /usr/local/sbin/nginx -c config/nginx.conf Stop using kill
$ kill -15 pid 4.3.2.3. Other Static Server Configurations
There are other Web server configurations and tools that will work well with Mongrel, including Pen, Pound, Litespeed, and others. You can find more details at the Mongrel Web site (http://mongrel.
|