codahale.com٭blog

go hotshot ringtone tomtomamr ringtonesgreen day ringtonebrother free mario ringtonechannel u ringtones
Coda Hale lives in Berkeley, CA, where he writes about Ruby on Rails, usability, web design and development, and the occasional bit about bicycles.

Time For A Grown-Up Server: Rails, Mongrel, Apache, Capistrano and You

More and more Rails developers are finding out that deploying a Rails application isn’t as simple as upload and rename; Rails apps work best when running all the time, and many Rails programmers are moving from traditional, shared hosts, like Dreamhost, to virtual private servers, like Rimuhosting, which allow them full control (and responsibility) of production servers.

Given this freedom, there are now a huge number of options available for deploying a Rails application, which is rare for such a new technology. So what to use? Apache + FastCGI? Lighttpd + FastCGI? SCGI? Apache 2? Litespeed? Mongrel? In what configuration? So many questions, so few answers. Here’s what I’ve been deleriously happy with, and how to do it yourself: Mongrel, Apache 2.2, and mod_proxy_balancer, using Capistrano to keep everything at your fingertips.

What the hell is Mongrel?

Mongrel is the hot new kid on the block. It’s a hybrid Ruby/C HTTP server designed to be small, fast, and brutally secure. It’s written by Zed Shaw, who is easily one of the most entertaining and delightfully cranky programmers I’ve ever read. (Zed, if you’re ever in the Bay Area, I owe you a pint.) While it’s a general purpose library, Mongrel is shaping up to be an amazing application server for Rails.

Sounds sweet. What’s Apache got to do with it?

Well, horses for courses. Mongrel is awesome at being a tight little application server for Rails, but when it comes to configurability, speed serving static files, and stability, Apache 2.2 beats the pants off Mongrel. But the main reason is that Rails does not play well with concurrency, and unless your code somehow magically gets around this, it will eat flaming death if it tries to do two things at the same time. So just Mongrel by itself would be slow at serving up static content like images, CSS files, etc., and it would necessarily be limited to a single request at a time, unless the main point of your Rails application was to publicly eat flaming death. (”It’s a feature!”)

So we’re going to be using Apache 2.2 as the front-end for Mongrel, which allows us to both serve up static content like it’s going out of style, but also to use a huge wealth of modules, like mod_deflate, which will improve your site’s responsiveness and download time. We’ll run a cluster of Mongrel servers locally, and route requests through Apache’s mod_proxy_balancer, which uses a sophisticated algorithm to make sure all the Mongrel servers feel equally loved.

Why not (Lighty|Pound|Litespeed|A Large Begonia)?

Apache is the heavy-weight in the web server world, and for good reason. It’s stable, fast, extensible, free as in Beery Speech, and all sorts of enterprisey. It’s gotten a bad rap in the Rails world, though, mainly due to its patchy FastCGI performance. It’s true, Apache + FastCGI is a horrible, horrible solution, unless your problem is “how can I waste my time on a dodgy server config?” in which case you shouldn’t be using the Intarweb while drunk. Finally, Apache currently has a great proxy balancer, which is why we’re using it.

This is not to speak ill of other front-end web servers, and you should feel free to use whatever you’re comfortable with. This article, though, is about how to set up what I’ve got set up, because I can vouch for it being awesome. Chip in on the comments if you’ve got a Mongrel band with a different lead singer and let us know how it’s going for you.

Okay, so what do I need?

I’m going to assume you’ve got Apache 2.2, Ruby 1.8.4, Subversion, and whatever database backend you need installed. That all depends on your operating system. Personally, I’ve had a great experience with Fedora Core 5, but I won’t make fun of you if you use Gentoo, Ubuntu, RHEL, Debian, FreeBSD, or whatever. Just make sure you can install and easily maintain your various pieces of software. Also, make sure you’ve got all the various low-level development tools, like a compiler or two, and the development packages for Ruby and such.

Your application has to be using either ActiveRecordStore, SQLSessionStore, or MemCached to keep track of session data. Files are the worst possible way to deal with sessions, and when you have more than one server reading and writing from the same file-based session store it’s gonna blow up big.

You should have a Capistrano script which will at least run the setup tasks correctly. If you need help with that, there are many blog articles and even a full-blown, if slightly outdated, manual on the damn thing.

Finally, none of this is going to work without root access (or an impossibly permissive server), and you’ll just piss off your admins if you try otherwise.

At this point you should have an Apache 2.2 “Welcome to Apache” style installation, and your Rails application should work just fine in WEBrick mode. If that doesn’t work, you’ve got problems which are best dealt with by tech support, IRC vets, or Friends Who Owe You Favors. If you aren’t at that stage yet, bookmark this page and get to work. I’ll wait until you’re ready.

Ready? Go!

1. Install Mongrel & Friends.

Because otherwise, the rest of this how-to is just going to be super awkward:

[server]$ sudo gem install daemons gem_plugin mongrel mongrel_cluster –include-dependencies

This will download, compile, and install Mongrel and its dependencies, daemons, a library which allows Mongrel to curl up at your server’s feet like a good little poochy poozle, and gem_plugin, which allows folks like yourself to write gem-based, module add-ons to Mongrel. It will also install mongrel_cluster, which contains a few tools which make managing a cluster of Mongrel servers easier.

Finally, it installs sendfile. I’ve already said that Mongrel is slow for static content, and it’s true. However, it’s a smart pup (and Zed’s a smart, smart man). In a proxying configuration, Mongrel will use sendfile, if it’s installed, to send Apache a reference to a file instead of reading it from disk and farting it out to Apache over a local HTTP configuration. This allows Mongrel to do the heavy lifting required of man’s best friend–running your Rails application–without getting bogged down in the minutae of CSS files, images, and Javascript files. Long story short: your site is faster. Many people skip installing sendfile, or don’t know about it, and because of this, they usally write Apache+Mongrel off as slow. Sendfile is the secret ingredient which allows Apache+Mongrel to be blazing fast.

I used to advise installing sendfile, but it doesn’t help–Apache serves the static content, so the 20%-or-so boost on static files is never seen–and it can even cause some pretty severe stability issues. So. No sendfile, and if you’ve got it installed, uninstall it, pronto. (This comes straight from Zed, who would know such things.)

Be sure to install at least mongrel_cluster (and thus, Mongrel) on your workstation–deployment via Capistrano will be complicated, otherwise, since you’ll have to reimplement all the code they’ve thoughtfully laid out for you already.

At this point you’re ready to get your Mongrel configuration on.

2. Mongrel: Sit! Lay! Restart!

First, you need to figure out how much memory you’ve got to spare, how much traffic you’re expecting, and how much money you’re willing to expend. An average Mongrel process can use between 15MiB and 40MiB of memory, depending on what your application does, and you need to figure out how many you can stuff into your server without popping it at the seams. Right now I’m running a decently-sized application with Apache, MySQL, and a cluster of three Mongrel servers in a 128MiB virtual private server with a bit of padding on top to keep the lid on. My advice is to start with two or three and build up to it. As you’ll see later, adding more clusters is stupid-easy. For now, we’ll assume that a cluster of three will do nicely.

Configuring the cluster

Pop open a terminal window, amble on over to your Rails project directory on your workstation, and crank out a cluster config file:

[workstation]$ mongrel_rails cluster::configure -e production \\
  -p 8000 \\
  -a 127.0.0.1 \\
  -N 3 \\
  -c /path/to/your/capistrano/setup’s/current

This will add a file, mongrel_cluster.yml, to your config directory, which, when run, will launch a cluster of three Mongrel servers, starting on port 8000, listening on the local interface (and not to evil meanies on the internet).

Before we get to using it, however, we’ll need to make one small change for testing purposes. Open up mongrel_cluster.yml, and comment out the line with address: 127.0.0.1 on it (it’s YAML, so just add a hash at the beginning of the line). We’ll add this back in later, but for now we’ll want to make sure our cluster is behaving properly. Add mongrel_cluster.yml to Subversion, and check it in.

Configuring Capistrano

Mongrel_cluster comes with some drop-in replacements for Capistrano’s restart and spinner tasks. Open your deploy.rb and add the following to the top:

require 'mongrel_cluster/recipes'

Now add the following to your deploy.rb settings:

set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"

Make sure you don’t have any old code in your deploy.rb obscuring the dark, shining beauty of mongrel_cluster. Also be sure you add the :mongrel_conf statement after setting :deploy_to. Otherwise, as Jesse Clark notes in the comments below, you’re in for some weirdness.

Configuring the services

Finally, we need to register your Mongrel cluster as a system-level service, which will allow us to make sure it pops back up when your server reboots.

First, open a terminal window in your server’s services script directory. For most of you, this will be /etc/init.d/. Link the mongrel_cluster script from the gem directory to the services directory:

[server]$ sudo ln -s /usr/lib/ruby/gems/1.8/gems/mongrel_cluster-0.1.3/resources/mongrel_cluster mongrel_cluster
[server]$ sudo chmod +x mongrel_cluster

Those you on Red Hat-based systems should add mongrel_cluster as a recognized service:

[server]$ sudo /sbin/chkconfig –level 345 mongrel_cluster on

If you’re running a Debian flavor, Ben Curtis assures me this works:

[server]$ sudo /usr/sbin/update-rc.d mongrel_cluster defaults

Those of you using otherwise will have to fend for yourselves. (Let me know how!)

Finally, link your mongrel_cluster.yml from your app’s config directory to /etc/mongrel_cluster:

[server]$ sudo mkdir -p /etc/mongrel_cluster
[server]$ sudo ln -s /your/rails/app/config/mongrel_cluster.yml /etc/mongrel_cluster/yourapp.yml

At this point, your server is rarin’ and ready to go.

Testing your cluster

Well, time to deploy, eh? Almost.

Before you begin, make sure your server can access your Subversion repository. Capistrano unfortunately doesn’t allow you to enter a password when Subversion prompts you for one, so go to a temporary directory and check out the entirety of your application. Subversion will remember your passwords once you’ve entered them.

Got your server playing well with Subversion? Then you’re ready to go!

In a loud voice, say something profound and memorable (”That’s one small step for Rails…”), and deploy that bastard:

[workstation]$ cap cold_deploy

This should checkout the latest version of your code, set up all the symlinks and other fun stuff, and finally start the Mongrel cluster. If it doesn’t, try running it with --trace and see what’s going on. Nine times out of ten, it’s some fiddly bit you forgot about in your haste to get this thing up and running.

If all went well (or was fixed after you let the magic smoke out), you should have three web servers running on your server:

  • http://myserver.com:8000
  • http://myserver.com:8001
  • http://myserver.com:8002

Visit each one in your web browser, and make sure everything works. Fix all the problems you see until each works fine.

Closing up the cluster

Once everything is to your satisfaction, open config/mongrel_cluster.yml back up again, and uncomment the address: 127.0.0.1 line. Save and check in your changes, and re-deploy:

[workstation]$ cap deploy

Everything should go smoothly. Make sure the three 800x ports on your web server are no longer accessible–the only public entrance to your web site should be through Apache!

Now your cluster backend is done! Congrats. Go get a beer, or whatever refreshing beverage the grown-ups let you have. Time to get to work on the front-end.

3. Putting The Inukchuk In Apache

First, find out where your Apache config files are. If your distro isn’t a total crazy-pants, it’ll be something like /etc/httpd/ or /etc/apache2. Within that directory should be conf.d, which is where all of your server-specific config files go. We’re going to take a DRY approach to all this, and try to reuse as many bits of our config files as possible, to avoid the all-too-common problems associated with overlapping anything. Now, all files in the conf.d directory which end in .conf will be automatically included. Keep that in mind.

Removing the cruft

Your Apache installation no doubt includes a certain amount of cruft. Some of that you will need to remove immediately, like config files which block what we’re trying to do, and some of it you’ll want to remove later, like modules you don’t need.

In my installation, at least, the ‘Welcome to Fedora Core 5′ page that every URL produced was created by a default file, welcome.conf. It’s in the way, so out it goes:

[server]$ sudo mv welcome.conf welcome.conf.disabled

Let’s lay out the file structure I’ve been using to keep my config files sane:

myapp.common
The common portions of our configuration. Refactoring this out makes it easier to add additional VirtualHosts down the road (e.g., SSL) while still maintaining exactly the same configuration.
myapp.conf
The main entry, tying everything together to produce a working Rails app.
myapp.proxy_cluster.conf
A proxy balancer with which to interface with the Mongrel cluster.
myapp.proxy_frontend.conf
An (optional) HTTP front-end for managing the proxy load balancing configuration on the fly.

Feel free to replace ‘app’ with the actual name of your application.

And now, for the meat.

myapp.common

The common bits of configuration. This links a Directory or VirtualHost with the proxy-balancer, includes the proper mod_rewrite configuration for Rails, adds support for Capistrano’s enable_web and disable_web commands, and enables mod_deflate for most compressible formats.

  ServerName myapp.com
  DocumentRoot /var/rails/myapp.com/current/public

  <Directory "/var/rails/myapp.com/current/public">
    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
  </Directory>

  RewriteEngine On

  # Make sure people go to www.myapp.com, not myapp.com
  RewriteCond %{HTTP_HOST} ^myapp\.com$ [NC]
  RewriteRule ^(.*)$ http://www.myapp.com$1 [R=301,L]
  # Yes, I’ve read no-www.com, but my site already has much Google-Fu on
  # www.blah.com. Feel free to comment this out.

  # Uncomment for rewrite debugging
  #RewriteLog logs/myapp_rewrite_log
  #RewriteLogLevel 9 

  # 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://mongrel_cluster%{REQUEST_URI} [P,QSA,L]

  # Deflate
  AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/javascript text/css
  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

myapp.conf

This is pretty simple, it just ties the settings in myapp.common to a VirtualHost on port 80.

<VirtualHost *:80>
  Include /etc/httpd/conf.d/myapp.common

  ErrorLog logs/myapp_errors_log
  CustomLog logs/myapp_log combined
</VirtualHost>

myapp.proxy_cluster.conf

This is loaded by Apache to configure a mod_proxy_balancer cluster mapped to the internal Mongrel servers.

<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>

myapp.proxy_frontend.conf

This provides a front-end for the proxy load balancing, which you can access from inside your server at http://localhost:8080.

Listen 8080
<VirtualHost *:8080>
  <Location />
    SetHandler balancer-manager
    Deny from all
    Allow from localhost
  </Location>
</VirtualHost>

4. Reboot And Go!

Time to kick over httpd and see if everything worked.

[server]$ sudo /sbin/service httpd restart

If all goes well, your web server is now configured as a Mongrel cluster backend to an Apache 2.2/mod_proxy_balancer frontend. You should feel happy.

5. Bonus Round! Secure server!

This one will depend greatly on your distro, but it does contain one super-important tip for getting a TLS/SSL version of your Rails app working in this setup.

Install mod_ssl, if you haven’t already

[server]$ sudo apt-get install mod_ssl

Replace the defaults in /etc/httpd/conf.d

My install added a file, ssl.conf to the conf.d directory. We’ll use this as a starting point, but let’s do it on our own terms:

[server]$ sudo mv ssl.conf ssl.conf.original
[server]$ sudo cp ssl.conf.original myapp.secure.conf

Now open myapp.secure.conf in your favorite editor (vi, right?), and scroll down to the VirtualHost it adds on port 443 (with Fedora Core 5, this was line 81). Inside the VirtualHost, add this:

Include /etc/httpd/conf.d/myapp.common

# This is required to convince Rails (via mod_proxy_balancer) that we're
# actually using HTTPS.
RequestHeader set X_FORWARDED_PROTO 'https'

That last bit is super important, especially if you’re using the ssl_requirements plugin from 37signals (and why wouldn’t you?). Otherwise, the Mongrel servers won’t know if an incoming request came in secure or not, which means you’ll have no way of knowing if you really should be processing that credit card or not.

Configure the certificates

Now, either look up the SSLCertificateFile and SSLCertificateKeyFile entries in myapp.secure.conf and replace those files with your cert and key, respectively, or edit the entries to point to where you have your cert and key stored.

Restart the server and test

[server]$ sudo /sbin/server httpd restart

Now see if that puppy works!

How well does this actually work?

Personally, it’s worked incredibly well. My “banging tin pots together” benchmarking with httperf indicated that where the Apache1.3+FastCGI setup on Dreamhost could handle ~30 reqs/sec before it would start dropping connections, the Apache2.2+Mongrel setup on a 128MiB Rimuhosting VPS can handle ~90 reqs/sec before things get hinky. In addition, the amount of downtime due to lost worker threads or fudged FastCGI connections was nil. The only times the site went down could be directly traced to me cutting first and measuring second.

Apache+Mongrel is shaping up to be the preferred deployment platform for Rails applications. Recently, the official Ruby On Rails site moved to Apache+Mongrel for their blog, wiki, and manuals site, all of which are much more responsive and have much lower downtimes. Rails Machines, an exciting new “rapid application deployment” hosting service for Rails applications, is using Apache+Mongrel for all their services. Rick Olsen, Rails Core member, has been running both his blog and Rails Weenie on ApacheLitespeed+Mongrel recently, and some people like Jonathon Weiss have moved large sites over to this architecture.

The great thing about this deployment architecture is that it leverages one of Rails’ greatest strengths: share-nothing scaling. All you have to do is add more boxes, and Apache+Mongrel makes that as easy as changing your deployment recipe and your myapp.proxy_cluster.conf file, then restarting the services. Your Mongrel clusters can span boxes and networks, making scaling a simple matter of plugging in hardware.

Long story short: it’s golden.

Thanks to…

I cribbed much of the initial Apache configuration and Mongrel ideas from Bradley Taylor’s Fluxura blog, as well as Jonathan Weiss’s article. Any errors I’m willing to acknowledge as my own, but leave a comment if you find something that doesn’t work for you! Finally, thanks to all the commenters with questions, corrections, and thanks. This article wouldn’t be nearly as accurate without you all. Thanks for trying to follow my instructions. ;-)

Enjoy!

258 Responses to “Time For A Grown-Up Server: Rails, Mongrel, Apache, Capistrano and You”

  1. Jim Says:

    If I recall Rick is running litespeed on his blog and rails weenie.

  2. Elliot Smith Says:

    Coda, you are a Jedi master. Many thanks for this, most useful.

  3. Ryan Daigle Says:

    And I won’t make fun of you for using Fedora Core :)

    Nice writeup, thanks!

  4. Ben Curtis Says:

    Here’s the line to get Debian to set up the init script:

    sudo /usr/sbin/update-rc.d mongrel_cluster defaults

  5. Bob Says:

    Great article, when I’m ready to start experimenting I will be back…

    Typo in the article if you are interested?
    “My advice is to start with two or three and build up to it. As you’ll see later, adding more clusters is stupid-easy. For more, we’ll assume that a cluster of three will do nicely.”

    “For more,” probably should have been “For now,”

  6. steve enzer Says:

    Great article! Just what I was looking for.

    I did notice what appears to be an error, in this section:

    Now add the following to your deploy.rb settings:

    set :mongrel_servers, 3
    set :mongrel_port, 8000
    set :mongrel_environment, ‘production’
    set :mongrel_config, “#{current_path}/config/mongrel_cluster.yml”

    I believe that the last line actually needs to be:

    set :mongrel_conf, “#{cur…

    or at least, using the current version of mongrel_cluster it does

  7. Coda Says:

    Thanks a million, Steve! That bit of duplication always made my teeth itch, but I couldn’t get the config file to load on its own. Conf, not config. Awesome!

  8. How to setup a tight Rails deployment server with Apache and Mongrel Says:

    [...] The unstoppable Coda Hale presents an amazing article about setting up a server with Mongrel, Apache, Capistrano, SSL support, etc. for solidly serving Rails applications. An extremely well written and solid guide. [...]

  9. Bloggitation » links for 2006-06-21 Says:

    [...] Time For A Grown-Up Server: Rails, Mongrel, Apache, Capistrano and You (tags: ruby rails sysadmin mongrel) [...]

  10. Jesse Clark Says:

    Thanks for the resource, I found a couple things as I was going through it:

    [workstation]$ mongrel_rails cluster::configure -e production \
    -p 8000 \
    -a 127.0.0.1 \
    -N 3 \
    -C /path/to/your/capistrano/setup’s/current

    with this config command I get Errno::EISDIR.

    Not having read the mongrel documentation (…) it took me a while to (incorrectly) assume that it was trying to write the config file to the path given to -C.

    Much much later, I figured out that instead of giving it the path name to the config file, you might have meant to pass a lower case -c which would cause the mongrel_rails start commands to chdir to your deploy directory before executing which allows all the default paths to function correctly.

    4 hours and one case change later, it was off to the races.

    Another small point is that
    set :mongrel_conf, “#{current_path}/config…
    references current_path which references deploy_to and you’ll get odd results if you try to set mongrel_conf prior to deploy_to.

  11. Coda Says:

    Ack! Sorry about wasting four of your hours, Jesse! That was my left pinky getting a little eager with the shift button. And good point on the :mongrel_conf.

  12. steve enzer Says:

    Coda, now that I’ve installed Apache 2.2 and configured the cluster, all I’m getting is a blank page with ‘It Works’ writ across the top in large type — and I’m a bit at a loss as to what that means (or doesn’t mean), as I’d expect (or hope) to be seeing my app… any idea?

  13. Coda Says:

    Hmmm… that sounds like the default configuration of Apache, which you’ll need to disable, so your own configuration can show up.

    In your conf.d directory, there is probably something like welcome.conf which you’ll need to rename to something like welcome.conf.disabled or somesuch.

    If this isn’t the case, then your distro packagers felt like tossing modularity to the wind, and stuffed that portion of code directly into httpd.conf in the conf directory.

    Failing that, you may want to fall back on the advice of #apache on FreeNode.net.

  14. Cyrus Farajpour Says:

    I’ve spent the past few days setting up a very similar hosting environment and was thinking about making a write up myself. Now I see yours and I must say thank you. Your setup points out flaws I didn’t even think of in my own and encompasses (SSL in particular) more than I would have.

    This is a really kickass article.

    ~smoil

  15. Rails, Mongrel, Apache, Capistrano and You · mornography.de Says:

    [...] Coda Hale schlägt wieder zu: Time For A Grown-Up Server: Rails, Mongrel, Apache, Capistrano and You. Eine Rundum-Sorglos-Anleitung zum Aufsetzen einer Rails-Anwendung mit Mongrel und Apache 2.2. Über das wundervolle Capistrano. Boochakayaya! [...]

  16. Jesse Clark Says:

    It would have taken me quite a bit longer to get this far without this guide you have provided. I don’t consider the four hours wasted at all and I’m glad that I could contribute in some small way to your excellent article.

  17. Bradley Tayloy Says:

    Nice writeup! Much of this is now automated using the railsmachine gem which I have released as open source. By default, the paths are configured to work with our server configurations, but you should be able to change the appropriate variables for your server.

    To install:
    “gem install railsmachine”

    Quick start guide:
    https://support.railsmachine.com/index.php?pg=kb.page&id=12

  18. Ben Says:

    Coda,
    Thanks for the great blog and plugins all the time… I checked out Rimuhosting and they look like a good fit for what I do. Are you hosting with them now? If you are tell me what domain your hosting with them and you will get a $15 referring credit.
    Thanks,
    Ben

  19. Coda Says:

    Ben– I am indeed hosting with Rimuhosting, and their service has been flawless. Any and all downtime we’ve experienced with them has been strictly due to Sausagefingers McGunjumper (read: me, pushing buttons when I shouldn’t). If you want to toss me a credit, the domain is gpsgeek.com, but it’ll go to my employer, not me.

  20. Jesse Clark Says:

    FYI mod_proxy_balancer was released with Apache 2.1 which is therefore the minimum apache requirement for this setup.

  21. Le blog » links for 2006-06-22 Says:

    [...] Rails, mongrel and Apache Enfin un tutorial pour installer Rails d’une façon efficace et compatible avec Apache, pour m’éviter d’avoir de multiples serveurs web. Et, finallement, ça ressemble vachement à ce qu’on fait en Java. (tags: development hosting rails ruby server software tutorial web apple) [...]

  22. Andi Says:

    Great post, thanks a lot for summing all this up. I wonder if this virtual hosting with 128MB ram is enough. I’ve been thinking of going virutal too, but was always scared by the low RAM they provide, especially with hungry Apache. Any problems with the size of the RAM? Machine must be swapping all the time….?

  23. Coda Says:

    You know, it’s not doing anything else but running Apache, Mongrel, and MySQL. It’s not the most roomy environment, but we honestly haven’t had any problems with it yet. Smaller sites can probably use two Mongrel processes, which would easily fit in a 96MiB VPS.

  24. JGeiger Says:

    Please be sure to read On Boot Initialization Setup in http://mongrel.rubyforge.org/docs/mongrel_cluster.html as it contains information about copying your config files to where the startup script can find them. You might want to add this information into the post as well.

  25. Coda Says:

    Crap, thanks JGeiger! I knew I forgot to write up a step.

  26. Richard Livsey Says:

    Hi - thanks for the great tutorial. In combination with Ezra’s ‘perfect rails stack’ article (http://www.brainspl.at/rails_stack.html) I nearly have my new dedicated server up and running.

    I installed Apache2 from apt-get and all is good, except it doesn’t seem to include mod_proxy_balancer and I can’t seem to work out where to get it from. Any ideas on how to solve this last step would be greatly appreciated!

    Thanks again.

  27. William Says:

    Coda - thank you. A much needed article. ‘Best arguments I’ve read thus far for the Apache2/Mongrel setup. Looks like I need to rearrage a few things and dig in ASAP. I’ll let you know how it goes.

  28. Richard Livsey Says:

    Ooops - Found out that the apt-get version of apache2 is 2.0 and not 2.2 which is the version which comes with mod_proxy_balancer!

    Nuked the apt-get version and installed 2.2.2 from source and all works superbly now!

    Thanks again for the great article :o)

  29. Dan McCormack Says:

    I set this all up today (I’d previously been running Apache 2.0 + FCGI) and I’m loving it. I ran into a problem though. My Rails app lives in a subdirectory of my site, so for example my ProxyPass lines look something like this:

    ProxyPass /test/ balancer://mongrel_cluster/
    ProxyPassReverse /test/ balancer://mongrel_cluster/

    That works, but the paths are all wrong because Rails thinks it’s at the root directory (which, as far as it’s concerned, it is), so it generates links to things like /controller/action instead of /test/controller/action, as it did when I was running it with FCGI. Does anyone have any idea how I might work around this issue? Maybe some clever mod_rewrite rules, or doing something with the routing, or somehow altering Mongrel’s configuration to place the Rails site in a subdirectory to match the Apache config? I’ll be experimenting with a few of these, but if someone has encountered this issue before I’d love to hear how you dealt with it.

  30. Milos Says:

    […] A very accosting layout and a interesting discussion topic, do you provide any Web-based services to universities or students. […] - Sorry for the stupid question :-)

  31. Cyrus Farajpour Says:

    To: Dan McCormack

    I solved this issue by using the reverse_proxy_fix plugin.

    ruby script/plugin install http://svn.napcsweb.com/public/reverse_proxy_fix

    Lemme know if this works for you.

    ~Cyrus

  32. Dan McCormack Says:

    Cyrus: Perfect! With a little modification, that solved my problem exactly. I love the internet. Thanks :)

  33. Charles Brian Quinn Says:

    Kudos, an excellent write-up indeed. Here are my notes/additions:

    in gentoo the startup is:

    $ sudo rc-update add mongrel_cluster default

    and if you symlink (your symlinked) mongrel_cluster config you don’t have to worry about changing that one sitting in /etc/mongrel_cluster:

    $ ln -s /path/to/your/capistranoed/app/current/config/mongrel_cluster.yml /etc/mongrel_cluster/yourapp.yml

    I just got done converting one of our boxen from a lighttpd + externally managed fastcgi over to apache 2.2 mod_proxy_balancer + mongrel_rails on a smokin’ machine. I used siege to load_test her, and will be posting the results soon!

    It would be cool to be able to somehow tell apache’s mod_proxy_balancer how many mongrel_rails exist dynamically — the hacker in me says there’s a way to build up those lines “http://127.0.0.1:8000 …” based on your mongrel_cluster file. Perhaps another day. ;-)

    Thanks a bunch for the great field notes!

  34. Dave Says:

    Hi there,

    Great article!

    I did run into a problem, and I’m not real sure what’s causing this. When I run “rake remote:cold_deply” cap freezes at the following line:

    [192.168.0.200] executing command
    ** [out :: 192.168.0.200] Authentication realm: swaydev
    ** [out :: 192.168.0.200] Password for ‘dave’:
    ** [out :: 192.168.0.200] subversion is asking for a password
    ** [out :: 192.168.0.200] Authentication realm: swaydev
    ** [out :: 192.168.0.200] Username:

    It won’t let me enter a username at this point. Everything just freezes.

    Any ideas?

    Thanks!
    Dave

  35. Dave Says:

    Woops… I meant:

    “rake remote:cold_deploy”

    (forgot the “o”)

    -Dave

  36. Coda Says:

    Dave–that’s a little-known gotcha of Capistrano’s. You need to make sure the account you’re using with Capistrano can access your Subversion repository for each app server of yours. Log into each and svn co your_repos into a temp directory. It’ll prompt you for the username and password, and once you’ve entered it successfully, it’ll remember it. Then you’ll be able to deploy without any problems.

  37. Dave Says:

    Thanks Coda… I can’t believe I missed that!

    -Dave

  38. Doug Says:

    Cluster works for me but not with Apache uhh!
    Using the most basic setup I can think of to get this running. Created a basic rails app structure and configured mongrel. Started mongrel and can access the riding rails page from a browser at http://localhost:8000, http://localhost:8001, etc.

    Problem is when using appache at http://localhost - it loads the riding rails page with no image, and when I click the “About your applictions environment” I get an Apache page: Service unavailable. Checking /etc/httpd/logs/myapp_errors_log shows: Permission denied: proxy: HTTP: attempt to connect to 127.0.0.1:8000 (127.0.0.1) failed

    I’m transitioning (painfully) from a long Windows career to Linux so I’m sure I’m missing something silly here. Any ideas or places for me to look? I’ve checked all the directions in your post about 5 times and can’t find where I went wrong.

    Thanks,
    -Doug

  39. Coda Says:

    Doug–The “About your application’s environment” link will only work for local requests due to security reasons. In the production environment, none of the requests Mongrel receives from Apache will be considered local, and so Mongrel will issue a 403 error: permission denied. This seems like a likely source of your problem. You may want to add a controller to your Rails project and give it a simple index action.

    If that doesn’t work, the problem probably lies in the way you have configured your proxy cluster in Apache. If you email me your config files for that, I’d be able to tell you more.

  40. Jed Hurt Says:

    Hey Coda, I have a Spry VPS with Apache 2.0.46 and I’m too scared to try to upgrade it. Does Apache 2.0.46 have the necessary components to complete this walkthrough?

  41. Coda Says:

    Sorry, Jed. Only people with Apache 2.1 and up can play. You may want to talk to the folks in #apache about the advisability of compling Apache from scratch on your system. It may be easier than you think.

  42. schwuk.com Says:

    Daemonizing Mongrel…

    I did have one minor niggle though. After restarting my server a couple of times during the aforementioned problems I had to restart Mongrel manually. I knew there was a better way to do it, but I didn’t know how. Now I do…

  43. Anonymous Says:

    Time For A Grown-Up Server: Rails, Mongrel, Apache, Capistrano and You…

    How to setup a web server, configured as a Mongrel cluster backend to an Apache 2.2/mod_proxy_balancer frontend….

  44. Paul King Says:

    Another thing worth noting is that you should probably configure apache to deny access to the .svn subdirectories. Problem is that I can’t seem to get the information here to work: http://subversion.tigris.org/faq.html#website-auto-update with this configuration.

    Anyone been able to successfully block access to .svn directories, if so where do you put the DirectoryMatch directive?

    Cheers

  45. Michael Says:

    Thanks a lot for this nice writeup, Coda, but there is one thing I don’t seem to get right. You mention that if you install the sendfile gem, mongrel won’t serve any static content but let apache do the work. So far so good, but shouldn’t the following rewrite rule from your myapp.common capture all static requests before mongrel even sees them?

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

  46. Michael Says:

    Regarding comment #44: You can set the variable :checkout to “export” in your deploy.rb and capistrano will perform an svn export instead of svn co, so you won’t get a working copy and thus no .svn directories at all on your server.

  47. Coda Says:

    Paul–I’m not sure if it’s the way I’ve got my routes mapped in my application, but my .svn directories aren’t publicly accessible. In terms of having Subversion automatically update things, you’re much better off using Capistrano.

    Michael–two reasons: one, I’m pretty sure it helps with cached content, two, the Apache configuration still lets a few things slide. Regarding the first issue, I’m not positive, and regarding the second, fixing that is on my to-do list, and I’ll update this post when I fix that. In the meantime, it’s a very little bit of extra effort to make the worst-case scenario (Mongrel serving static content) a bit less worst-case.

  48. Chad Westfall Says:

    In regards to Doug’s post on June 27th, 2006 at 4:52pm. I was running into a similar issue:

    (13)Permission denied: proxy: HTTP: attempt to connect to 127.0.0.1:8002 (127.0.0.1) failed

    I found the issue to by SELinux. My dedicated server host setup my box with SELinux enabled and it was causing an issue between mongrel and apache. To disable SELinux temporarily, run the following command:

    setenforce 0

    Conversly, “sentenforce 1″ will enable SELinux again.

  49. Paul Says:

    A minor thing — I believe the phrase is “a bad rap,” not “a bad wrap.”

  50. Jens Says:

    Hi all,

    I would like to use the apache2.2 and the mongrel cluser to serve more than one rails app (the apps run under different VirtualHost configurations). Do I have to create 3 mongrel processes for each VirtualHost entry or can I share (say 6-8 mongrel processes - yep I have enough Ram) between the apps ?

    Thanks a lot
    Great article BTW
    Jens Carroll

  51. Serving Rails with lighttpd, pound and mongrel Says:

    [...] Time For A Grown-Up Server: Rails, Mongrel, Apache, Capistrano and You | Archives | codablog | Coda Hale [...]

  52. Coda Says:

    Paul–Thanks!

    Jens–You can point many vhosts at a single cluster, but a cluster can only run a single application. You’ll need at least one cluster per application.

  53. Michele Says:

    Thanks for the great tutorial!

    A quick note for FreeBSD: Apache 2.2 should be installed with WITH_PROXY_MODULES=yes. i.e. cd /usr/ports/www/apache22 && sudo make WITH_PROXY_MODULES=yes && sudo make install .
    And these modules should be added to the ones added by default in /usr/local/etc/apache22/httpd.conf:
    LoadModule proxy_module libexec/apache22/mod_proxy.so
    LoadModule proxy_balancer_module libexec/apache22/mod_proxy_balancer.so
    LoadModule proxy_ftp_module libexec/apache22/mod_proxy_ftp.so
    LoadModule proxy_http_module libexec/apache22/mod_proxy_http.so
    LoadModule proxy_connect_module libexec/apache22/mod_proxy_connect.so

  54. ian Says:

    One problem I have run into is that my static (cached) pages are correctly served through apache, but my assets like javascripts and css are still served through mongrel.

    I think this has to do with all the requests automatically getting rewritten with a .html suffix ( RewriteRule ^([^.]+)$ $1.html [QSA]).

    I am not enough of a mod_rewrite guru to figure out a solution, but I am sure someone else has.

  55. ian Says:

    To follow up on my previous comment, I have resorted to adding the following lines to my config.

    ProxyPass /images !
    ProxyPass /stylesheets !
    ProxyPass /javascripts !
    ProxyPass /favicon.ico !

    This ensures that my static files get served from apache, and not delegated to mongrel.

    I found this solution on the mongrel mailing list archives.

  56. Coda Says:

    Ian–Thanks a million for that. I was following some of the threads there myself, and I’ve added your suggestions to the article.

  57. Pascal Says:

    Great post Coda! A lot of good ideas. I was able to do an install Mac OS X Tiger (10.4.7) if someone’s interested.

    Works greats so far.

    Here’s the post: http://blog.nanorails.com/articles/2006/07/11/installing-rails-on-mac-os-x-tiger

  58. Installing Rails on Mac OS X Tiger Says:

    [...] If you are only looking for the basics, Locomotive is probably what you need, if you want a grown-up rails setup on Mac OS Tiger, read on. [...]

  59. Seth Says:

    For those of us not yet on Capistrano, but just using a SCM like perforce…what’s the nice way to restart the mongrels after a server push?

  60. Coda Says:

    Seth, you really should take the time to set up Capistrano. It’s maybe 30 minutes of work and cap deploy means never having to say sorry. Also, it works with perforce.

    Besides that, if you’ve registered your Mongrel cluster as a service, the easiest way is to just restart that and let mongrel_cluster do its job.

    On Redhat-ish Linuxes:

    server$ sudo /sbin/service mongrel_cluster stop
    server$ sudo /sbin/service mongrel_cluster start

    On Debian-y Linuxes:

    server$ sudo /etc/init.d/mongrel_cluster stop
    server$ sudo /etc/init.d/mongrel_cluster start

    Or if you haven’t been playing around with services, you can always use mongrel_cluster itself:

    server$ mongrel_rails cluster::stop -C /path/to/your/mongrel_cluster.yml
    server$ mongrel_rails cluster::start -C /path/to/your/mongrel_cluster.yml

    But seriously… Capistrano.

  61. revoluser.com - URLs will save the world Says:

    [...] Time For A Grown-Up Server: Rails, Mongrel, Apache, Capistrano and You | Archives | codablog | Coda Hale Installing and deploying rails… (tags: rails rubyonrails webdev capistrano) Technorati Tags: [...]

  62. Coda Says:

    Finally rolled in some of the advice on mongrel-users to choose the mod_rewrite [P] option over the ProxyPass directives. That way all the static content gets served by Apache, not Mongrel.

    (Took me long enough, jeez.)

  63. Guy Naor Says:

    One small note on deploying using svn.

    My svn servers are all behind tightly controlled firewalls, and the only way to get at them is using ssh+svn using private/public key authentication (yes, I know, I’ve been called paranoid before). In addition, my servers get no access to the internet unless I manually poke a hole in the firewall temporarily - this help prevent downloading things into my machines even if there’s a security breach. This completely precludes using svn for deployment. But all is not lost!

    The way I deploy is I changed the capistrano recipe for checking out the code to do a local export to a temp directory, tar.gz it, and copy it over ssh to the server. Then on the server it is untar.gz’d into the same directory a checkout would put it.

    So all that changes is the update_code recipe, the rest is the same and you get a more secure setup.

  64. Coda Says:

    Guy, you’re paranoid. ;-)

    (Also, you could probably use Subversion over SSL using client certificate authentication, but since you’ve gone to all that trouble… nice hack.)

  65. Chad Says:

    Coda,

    I see you said you “rolled in some of the advice on mongrel-users to choose the mod_rewrite [P] option over the ProxyPass directives” All I can tell is that you removed the ProxyPass directives. I see the following in your myapp.common:

    # Redirect all non-static requests to clusterRewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-fRewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L]

    So am I to assume that everything else is static and sendfile handles the handoff? How can I see which files are being served by sendfile/apache? The mongrel.log didn’t seem to tell me. Any clarification of how this whole process works would be great!

  66. Le blog » Archive du blog » Début de passage à ligthttpd Says:

    [...] Comme j’ai envie de faire du Ruby chez moi, et que la solution Mongrel+Apache2 m’apparaît comme impossible à mettre en place sur mon Ubuntu, je suis en train de passer doucement à lighttpd et honnêtement, je suis séduit. Séduit par la simplicité apparente de la configuration et ses possibilités avancées (rha, le enhanced virtual hosting, ça m’a l’air génial, ça). Par contre, pour l’intégration de langages de scripts comme le PHP, ça me pose un petit souci, car il faudrait que j’installe PHP indépendament d’Apache, ce qui est difficle quand Synaptic se bloque automatiquement à chaque lancement. Mais ça, c’est un problème propre à la distribution que je travaille à résoudre. Tout ça pour dire quoi ? Simplement que le blog risque de devenir, pour un moment, un intermittent du web et que je m’en excuse. [...]

  67. Doug Johnston Says:

    Holy crap, that’s a great tutorial. I’m ecstatic about my newly constructed Apache 2.2/Mongrel/Capistrano setup. Thanks so much!

  68. Anatol Pomozov’s blog » Blog Archive » Apache, Mongrel and proxy error Says:

    [...] After reading this article I have became electric enough to try it on my current project that recently has gone to beta. [...]

  69. Jason Says:

    Great article. My new CRAM setup works *almost* perfectly. Anyone know why adding basic authentication into the Apache config doesn’t work? I get 404 errors for all static pages and no auth for the rails app.

  70. Hammed Says:

    I just got a VPS account on rimuhosting.com which has Debian Sarge installed which doesn’t have an apt package for apache2.2. Any tips on building it from source with mod_proxy_balancer?

  71. Mongrel Cluster Says:

    [...] I just completed switching over Pecuniarius to use mongrel cluster. It would have probably been easy except that I had Apache 2.0 installed so that meant I needed to upgrade, and naturally I took the long route to do that (build from source numerous times until I got it just right) but I finally got Apache 2.2 with modproxybalance installed and hooked it up to a brand spankin new mongrel cluster following the instructions on Code Hale’s blog (there is no way that’s a real name, but if it is its quite cool). This blog along with symphoniou.us are still running on single mongrel instances, but I’ll fix that soon. [...]

  72. Coda Says:

    Chad–those are indeed the changes. To see who’s serving up what, you can crack open a terminal and type curl -v (the URL) > /dev/null and it’ll print out the headers, which will include the server type. The general process is that Apache checks to see if the file exists on disk (if it doesn’t have a file extension, it assumes it’s .html). If it does, Apache serves it up. Otherwise, the request is proxied to Mongrel.

  73. Coda Says:

    Jason–I’m totally calling this setup CRAM from now on. Sounds much more aggressive than LAMP. No idea about your authentication issues–it works fine for me.

    Hammed–Sorry, haven’t done that. You may want to ask the folks at RimuHosting if you can switch over to Ubuntu, which has 2.2 packaged. Failing that, I’m sure the folks in #apache or #debian would have some decent advice on the matter.

  74. Hammed Says:

    Thanks Coda, I was able to build Apache 2.2 from source - I had assumed it to be more complex than it turned out to be. Later I found instructions for the same in this post on the rimuhosthing forms:

    http://forums.rimuhosting.com/forums/showthread.php?t=230

    I’ve successfullly tested mongrel clusters on the server (yay!) but with capistrano and the same mongrel_cluster.yml, mongrel doesn’t start and complains

    !!! Path to log file not valid: log/mongrel.log

    It appears to be a simlink issue but I haven’t figured it out yet. Any ideas?

  75. Hammed Says:

    guys, make sure to run

    rake remote:setup

    before

    cap cold_deploy

    or you’ll get the !!! Path to log file not valid: log/mongrel.log error I was getting. The shared/log folder is created by the setup task. Duh.

  76. Michael Cho Says:

    guys…i’m a 2-month old newbie to the web-programming world…but Rails been a blast to play with…thou I can’t say for the deployment part (yet)…

    in any case, has anyone bump into this error while doing that “cap deploy” (i have a mongrel_rails restart task in my deploy.rb)?

    ** [out ] ** You have sendfile installed, will use that to serve files.
    ** [out ] !!! PID file log/mongrel.pid does not exist. Not running?
    ** [out ] restart reported an error. Use mongrel_rails restart -h to get help.

    Is that because when I subversion the project I ignored and removed the log files (as per the “HowtoUseRailsWithSubversion” guide)?

    Coda: thanks so much for the post! I’m learning alot going thro the steps! So u’r from Berkeley too? Did you go to that awesome kite festival over the weekend?

    peace folks..

  77. Coda Says:

    Michael–You may want to check out Hammed’s comment right above yours. Either you need to create the log directory, you need to give write permissions on the log directory to the user account that’s running the Mongrel processes, or you’re trying to cap deploy when you should be running cap cold_deploy (or even cap setup).

    (And yeah–I’m in Berkeley. Didn’t go to the kite festival, but I see them occasionally when I ride my bike along the bay to Richmond.)

  78. Armando Says:

    Hey all — great tutorial so far, but I’ve hit a snag. I’m in the “Testing your cluster” section, and when mongrel_cluster tries to start, I get (output from only one of the 3 / it’s repeated 3 times):
    ———————————————————————–
    ** Daemonized, any open files are closed. Look at log/mongrel.8002.pid and log/mongrel.log for info.
    ** Starting Mongrel listening at 127.0.0.1:8002
    ** Starting Rails with production environment …
    /usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:666:in `register’: undefined method `resolve’ for nil:Mongrel::URIClassifier (NoMethodError)
    from /usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:850:in `uri’
    from /usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/bin/mongrel_rails:112:in `cloaker_’
    from /usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:832:in `listener’
    from /usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/bin/mongrel_rails:96:in `cloaker_’
    from /usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:750:in `initialize’
    from /usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/bin/mongrel_rails:83:in `run’
    from /usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel/command.rb:199:in `run’
    from /usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/bin/mongrel_rails:235
    from /usr/bin/mongrel_rails:18
    ———————————————————————–
    … so, I’m basically unable to continue. Any thoughts?

    - I noticed the comment about not using sendfile, so I’ve removed that
    - mongrel 0.3.13.3
    - mongrel_cluster 0.2.0
    - daemons 0.4.3
    - gem_plugin 0.2.1

    I’ve inspected the code at /usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb line 666, and it looks like the classifier member isn’t getting initialized for some reason. :-\

  79. Jon Maddox Says:

    ouch, i just set up my first cluster last night. I’m glad i came back here to reference the post again. Sendfile goes from the secret sauce to a bad influence? yikes…

  80. Armando Says:

    To clear up my comment #78 … I was completely stumped. Then I recompiled ruby, and re-gem-installed all my gems, and then things worked. I had a hard lock-up on my laptop a few weeks ago, so *maybe* some core ruby files got mangled. Otherwise, I have not idea. Anyways, thanks for the tutorial — it was quite helpful.

  81. Otim Says:

    Coda,
    i’ve got the mongrels doing their thing. its great. but apache mucks up the whole things. don’t think i have my virtualhosts right. could you please post a sample config of apache setup using name based virtual hosting?

  82. [post]PostModern » Blog Archive » Dog Days of an Indian Summer Says:

    [...] I’m talking about Capistrano, Rails, Apache, Mongrel. Coda Hale wrote a great article on setting it up. I used his basic procedure, tailored it to my specific needs/personality, and voila! CRAM! [...]

  83. bathow Says:

    Mongrel is the way to go. after struggling with FastCGI and the mysterious hangs, we finally gave up and switched over. Aside from seeing Rails last year as the choice platform, this is the best decision we’ve made on the architecture side.

    now crispynews is humming along beautifully

  84. Ashish Says:

    Hi Coda,

    I am using Apache httpd 2.0.54 on Fedora Core 4.

    I tried to follow your instructions as well as those from various websites.

    However, getting Mongrel to run was a losing battle.

    I tried to upgrade to httpd 2.2.x. I also tried to upgrade my Fedora installation to Fedora Core 5. But only managed to break everything else including Plesk.

    Finally, I am back after a re-imaging of the server back at Fedora Core 4 with httpd 2.0.54.

    Does Mongrel run with Apache 2.0.54?

    If yes, can you please provide me with some help to setup Capistrano and SubVersion?

    Currently I am running Rails using Apache+CGI.

    Regards,

    Ashish.

  85. bryanthompson’s blog » Blog Archive » Apache2, Mongrel, Tiger, and proxy loadhandling install guide Says:

    [...] 3. Install mongrel (via http://blog.codahale.com/2006/06/19/time-for-a-grown-up-server-rails-mongrel-apache-capistrano-and-you/): sudo gem install daemons gem_plugin mongrel mongrel_cluster –include-dependencies [...]

  86. ThinkSplat Blog » Apache + mongrel Says:

    [...] This post is heavily influenced by the Time For A Grown-Up Server web page. I highly recommend you read that web page too for a more in-depth commentary of why you would want to do this. [...]

  87. steve dp Says:

    Awesome stuff man!

  88. Ashish Kulkarni Says:

    Managed to finally get Rails to run with Fedora Core 4, Apache 2.0.54 and SCGI.

    Details of the configuration

  89. Sean O'Hara Says:

    Is there any way to have specific directories point to something other than the mongrel cluster? For instance I have a /stats directory that I would like to maintain access to for web stats. But with the current setup it my Alias in apache for it is ignored. I tried adding ProxyPass /stats ! to my config but it doesn’t work. Any ideas?

  90. Jon Maddox Says:

    Sean, I just resolved that problem today by just using a subdomain. My weblog is powered by mephisto, and i’m using mint for stats. I put mint on a subdomain and they’re living happily with each other.

  91. Cayce Says:

    I’m having a ton of trouble getting my rails app firing. If I run just my mongrel cluster I can see my rails app going to http://10.104.0.121/website/index. I can also see the rolling on rails intro page at http://10.104.0.121.

    However, once I fire up Apache, I still get the rolling on rails intro page, but my app doesn’t fire. I get the following errors in my log:

    [Wed Aug 23 11:03:29 2006] [error] [client 10.70.120.45] no authorization providers configured
    [Wed Aug 23 11:03:29 2006] [error] [client 10.70.120.45] File does not exist: /home/rails/prtrack/public/website

    I don’t have the server dns setup yet, not sure if that has any impact. It just seems that Apache is not routing non-static requests to the cluster the right way.

    I’d really appreciate any help, pointers or guidance in the right direction.
    c.

  92. Cayce Says:

    I have narrowed the problem down to rewrite rules. I have my rails app firing now. I am getting log information on rewrites, so I know that mod_rewrite is operating. It appears, however, that rewrite rules in my railsapp/public/.htaccess file are overriding those in my .conf file(s). Never does the rule invoking the proxy get executed. I have tried setting AllowOverride All/None for various subdirectories in my .conf file to no avail - either the server comes back with “file not found” or it executes the rails app via apache > dispatch.cgi and avoids the mongrel proxy.

    Again, any assistance would be greatly appreciated.

  93. Coda Says:

    Cayce–You can uncomment the rewrite debugging levels in the configs and check the Apache logs for more possibilities. You may also want to check out the #apache channel on Freenode. They’re very helpful.

  94. Cayce Says:

    Turning on those logs is how I figured out what I have to this point. It’s very strange - I can see the various rewrite rules firing in the log file, but it’s only the ones from the rails app public/.htaccess file. It’s just never getting to/firing any of the rewrite rules from my .conf file(s) setup per your article.

    In any event - it’s a problem with rewrite rules on my setup, not anything with your article, which successfully got me almost there. I appreciate the help. I’ll check out the freenode channel.

  95. Cayce Says:

    Just an update - put my app in a sub-folder, used ProxyPass as noted by Dan M. above with Cyrus’ reverse_proxy_fix plug-in and everything is smooth sailing now.

  96. Dave Says:

    I am probably missing something really simple here but I dont really understand what the -c parameter is pointing to in the cluster::configure command:

    [workstation]$ mongrel_rails cluster::configure -e production \
    -p 8000 \
    -a 127.0.0.1 \
    -N 3 \
    -c /path/to/your/capistrano/setup’s/current

    Path to my capistrano setup’s current what?

    What path is that supposed to be pointing to? The path to my deploy.rb?

  97. Dave Says: