about summary refs log tree commit homepage
path: root/site/src/docs
diff options
context:
space:
mode:
Diffstat (limited to 'site/src/docs')
-rw-r--r--site/src/docs/SimpleLighttpdMongrelSetup.jpgbin0 -> 13747 bytes
-rw-r--r--site/src/docs/apache.page481
-rw-r--r--site/src/docs/choosing_deployment.page178
-rw-r--r--site/src/docs/contrib.page199
-rw-r--r--site/src/docs/debian-sarge.page289
-rw-r--r--site/src/docs/distributed_worker.page105
-rw-r--r--site/src/docs/frameworks.page34
-rw-r--r--site/src/docs/gem_plugin.page335
-rw-r--r--site/src/docs/how_many_mongrels.page90
-rw-r--r--site/src/docs/howto.page490
-rw-r--r--site/src/docs/index.page107
-rw-r--r--site/src/docs/lighttpd.page278
-rw-r--r--site/src/docs/litespeed.page84
-rw-r--r--site/src/docs/mongrel_cluster.page138
-rw-r--r--site/src/docs/osx.page124
-rw-r--r--site/src/docs/pen_balance.page57
-rw-r--r--site/src/docs/pound.page148
-rw-r--r--site/src/docs/security.page94
-rw-r--r--site/src/docs/started.page83
-rw-r--r--site/src/docs/upload_progress.page136
-rw-r--r--site/src/docs/upload_progress_form.rhtml53
-rw-r--r--site/src/docs/upload_progress_javascript.js113
-rw-r--r--site/src/docs/upload_progress_rails.rb14
-rw-r--r--site/src/docs/win32.page131
24 files changed, 3761 insertions, 0 deletions
diff --git a/site/src/docs/SimpleLighttpdMongrelSetup.jpg b/site/src/docs/SimpleLighttpdMongrelSetup.jpg
new file mode 100644
index 0000000..bdb2bb1
--- /dev/null
+++ b/site/src/docs/SimpleLighttpdMongrelSetup.jpg
Binary files differ
diff --git a/site/src/docs/apache.page b/site/src/docs/apache.page
new file mode 100644
index 0000000..ab26510
--- /dev/null
+++ b/site/src/docs/apache.page
@@ -0,0 +1,481 @@
+---
+title: Apache
+inMenu: true
+directoryName: Apache
+---
+
+h1. Apache Best Practice Deployment
+
+h3. By Charles Brian Quinn
+
+The preferred setup (for now) is to put Mongrel behind an Apache 2.2.3
+server running mod_proxy_balancer.  Apache is a proven web server, runs
+half the Internet, and is a pain to configure.  These instructions should
+get you started, but refer to the Apache folks for anything more complex
+or weird.
+
+When you're just starting out, don't bother with doing anything but
+running just Mongrel.  Mongrel is slower than Apache, but not so slow that
+small installations will notice it.  The worst thing you can do is
+try to learn Apache install when you're also trying to learn Ruby on Rails
+and Mongrel too.  Start small, then *when you need*, build up to the big stuff.
+
+h2. A simple single mongrel configuration
+
+Start up a single mongrel instance on port 8000:
+
+<pre><code>
+  $ mongrel_rails start -d -p 8000 \
+   -e production -P /full/path/to/log/mongrel-1.pid
+</code></pre>
+
+Now, we'll tell Apache to simply proxy all requests to the mongrel server
+running on port 8000.  Simply add the following to your httpd.conf or in
+a vhost.conf file:
+
+<pre><code>
+  <VirtualHost *:80>
+    ServerName myapp.com
+    ServerAlias www.myapp.com
+
+    ProxyPass / http://www.myapp.com:8000/
+    ProxyPassReverse / http://www.myapp.com:8000
+    ProxyPreserveHost on
+  </VirtualHost>
+</code></pre>
+
+That's it, in a nutshell.  Several things to note in this configuration:
+
+1) This configuration forwards all traffic to mongrel.  This means mongrel
+will serve images, javascript, files, and everything else.  It's quite fast
+at this, but Apache can do it better.
+
+Here are some basic proxypass rules you can add to tell the ProxyPass not
+to forward on requests to certain documents/requests:
+
+<pre><code>
+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
+</code></pre>
+
+For a more detailed set of rules for forwarding on all dynamic content to mongrel,
+see the more detailed configuration below for more details.
+
+2) In this configuration, it is entirely possible that two users (web
+requests) could hit your application at the exact same time, and one would
+have to wait literally milliseconds until the first request is finished
+before having a turn at the mongrel instance.  Unless you've got some really
+long HTTP processes, the nature of the HTTP protocol is pretty good at waiting
+in line. Only you can determine ("through metrics":http://mongrel.rubyforge.org/docs/how_many_mongrels.html) how long and
+how many users will come at your application at the exact same time.
+
+Sufficient to say, if you're ready to start scaling with multiple mongrel
+instances, read on.
+
+h2. Using multiple mongrel instances with mod_proxy_balancer
+
+First, let's start up a few mongrel instances (*nix-style):
+
+<pre><code>
+$ mongrel_rails start -d -p 8001 \
+   -e production -P log/mongrel-1.pid
+$ mongrel_rails start -d -p 8002 \
+   -e production -P log/mongrel-2.pid
+$ mongrel_rails start -d -p 8003 \
+   -e production -P log/mongrel-3.pid
+$ mongrel_rails start -d -p 8004 \
+   -e production -P log/mongrel-4.pid
+</code></pre>
+
+You can also use "mongrel_cluster":http://mongrel.rubyforge.org/docs/mongrel_cluster.html by "Bradley Taylor":http://fluxura.com/ for
+managing several mongrel instances with a configuration file (and sysv init
+scripts for *nix servers).
+
+We're going to be requiring the use of mod_proxy_balancer, a "new feature":http://httpd.apache.org/docs/2.2/new_features_2_2.html in
+Apache 2.1/2.2 and above to proxy requests to
+our mongrel instances.  This software based HTTP load balancer will distribute
+requests evenly (applying a weighting and selection algorithm) to our mongrel
+instance(s).  It even comes with a swell load-balancing manager page for
+monitoring incoming requests.  For more information, see:
+"Apache's mod_proxy_balancer Documentation":http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html.
+
+h2. Obtaining Apache 2(.1+)
+
+I won't go into too many details, as windows and the various linux
+distributions all have several methods for obtaining apache2, but you will need
+the use of the following modules:
+
+ * mod_proxy, mod_proxy-html, and mod_proxy_balancer
+ * mod_rewrite
+ * mod_deflate
+ * mod_headers
+ * (optional) mod_cache and one of mod_memcache or mod_filecache
+ * (optional) mod_ssl
+
+If you're compiling from source, this configuration should do the trick:
+
+<pre><code>
+#./configure --enable-deflate --enable-proxy --enable-proxy-html \
+--enable-proxy-balancer --enable-rewrite --enable-cache  \
+--enable-mem-cache --enable-ssl --enable-headers
+</code></pre>
+
+h2. Configuring Apache2
+
+A good practice is the separation of apache configuration files.  Recommended
+by several other good guides, we'll be storing information for our application
+in several different files.  Put these files somewhere that apache2 knows
+about.  Apache is quite good about scanning for all .conf files in certain
+directories.
+
+h3. myapp.common
+
+Apache lets you include common configuration items into another configuration
+so you can cut down on repetition.  What we're going to do is make a file
+that has all the common junk that every Mongrel application needs to
+work at all, then we'll just include this in little .conf files for
+any application we deploy.
+
+Notice that this file doesn't end in .conf since it's not a real configuration
+file, but you can name it however you wish.
+
+<b>Important Update: "typo fixed in IE deflate rules":http://rubyforge.org/pipermail/mongrel-users/2006-October/001868.html</b>
+
+<pre><code>
+  ServerName myapp.com
+  DocumentRoot /var/www/myapp.com/current/public
+
+  <Directory "/var/www/myapp.com/current/public">
+    Options FollowSymLinks
+    AllowOverride None
+    Order allow,deny
+    Allow from all
+  </Directory>
+
+  RewriteEngine On
+
+  # Uncomment for rewrite debugging
+  #RewriteLog logs/myapp_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
+</code></pre>
+
+h3. myapp.conf
+
+We then take the above commmon file and include it in our configuration file
+for this application deployment.
+
+If you're using virtual hosting (a pretty good idea, even when you're the only
+one on the server), your sample configuration can be this simple:
+
+<pre><code>
+  <VirtualHost *:80>
+    Include /etc/httpd/conf.d/myapp.common
+
+    ErrorLog logs/myapp_errors_log
+    CustomLog logs/myapp_log combined
+  </VirtualHost>
+</code></pre>
+
+h3. myapp.proxy_cluster.conf
+
+This is the meat of our configuration, and goes hand in hand with our mongrel
+(or mongrel_cluster) configuration.  This configuration tells the apache2
+mod_proxy_balancer to proxy requests to 3 mongrel instances running on ports
+8000, 8001, and 8002.  
+
+<pre><code>
+  <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>
+</code></pre>
+
+If you had an seperate application server, you could balance to it easily by
+replacing the 127.0.0.1 with the ip or hostname of your application server, but
+be sure to make them listen on an external interface (rather than 127.0.0.1).
+
+When you add an additional mongrel to your mongrel_cluster, you can simply add
+an additional BalancerMember to this file, restart apache (or reload) and
+you're all set.
+
+h3. (optional) myapp.proxy_frontend.conf
+
+This optional file will setup the balancer-manager -- a simple front-end for
+viewing how your requests are being handled.  This balancer in the
+configuration below will only work from the localhost, so no one else (or
+possibly you) can view it unless you alter the "Deny" and "Allow" lines.
+
+<pre><code>
+Listen 8080
+<VirtualHost *:8080>
+  <Location />
+    SetHandler balancer-manager
+    Deny from all
+    Allow from localhost
+  </Location>
+</VirtualHost>
+</code></pre>
+
+h3. SSL Requirements
+
+In order for mongrel to know that this request has a forwarded protocol of
+https, we'll need to add a special header (hence the addition of mod_header,
+included in most apache2 builds).
+
+<pre><code>
+  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'
+</code></pre>
+
+You need this mostly so that redirects go back to https and so you can
+spot when people are coming through SSL or not.
+
+h2. Automation, Automation, Automation
+
+There are several great tools that automate the setup of Apache for use with
+mongrel and mongrel_cluster.  The "RailsMachine gem":https://support.railsmachine.com/index.php?pg=kb.chapter&id=18 can
+automate an entire setup of a Rails application.  Also, "Slingshot Hosting":http://www.slingshothosting.com/ has
+a sample set of "Capistrano recipes":http://www.slingshothosting.com/support/capistrano that automatically setup Apache2 and mongrel
+through the @rake remote:setup@ task.  Be sure to check out both for some ideas.
+
+h2. Running Multiple Rails Apps with Mongrel
+
+The newest version of Mongrel supports multiple Rails applications through
+the use of the --prefix command.  The Apache magic for proxying a
+single application is here assuming your prefix is app1:
+
+<pre><code>
+ProxyPass /app1 http://127.0.0.1:3000/app1
+ProxyPassReverse /app1 http://127.0.0.1:3000/app1
+</code></pre>
+
+You need to have the proxy pass the new directory name.
+
+Thanks to Joey Geiger and others of the mongrel list for these
+instructions.
+
+h2. Success Stories
+
+Martins on the mongrel-list has submitted this simple apache configuration.  It serves up static content with apache, and forwards dynamic content on to mongrel using ProxyPass.  Thanks Martins:
+
+<pre><code>
+<VirtualHost *>
+       ServerName myapp.tld
+       ServerAlias www.myapp.tld
+
+       DocumentRoot /var/www/sites/myapp/current/public
+
+       <Directory "/var/www/sites/myapp/current/public">
+               Options FollowSymLinks
+               AllowOverride None
+               Order allow,deny
+               Allow from all
+       </Directory>
+
+       RewriteEngine On
+
+       # Check for maintenance file. Let apache load it if it exists
+       RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
+       RewriteRule . /system/maintenance.html [L]
+
+       # Let apache serve static files
+       RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
+       RewriteRule (.*) $1 [L]
+
+       # Don't do forward proxying
+       ProxyRequests Off
+
+       # Enable reverse proxying
+       <Proxy *>
+               Order deny,allow
+               Allow from all
+       </Proxy>
+
+       # Pass other requests to mongrel instance
+       ProxyPass / http://127.0.0.1:8200/
+       ProxyPassReverse / http://127.0.0.1:8200/
+
+</VirtualHost>
+</code></pre>
+
+Phillip Hallstrom has submitted this apache configuration, which includes support for having static directories handled by Apache, php support, and hiding svn directories.
+
+<pre><code>
+<VirtualHost *:80>
+
+  ServerName myserver.com
+  DocumentRoot /path/to/my/app/public
+
+  <Directory "/path/to/my/app/public">
+    Options FollowSymLinks
+    AllowOverride None
+    Order allow,deny
+    Allow from all
+  </Directory>
+
+  <Proxy balancer://mongrel_cluster>
+    BalancerMember http://127.0.0.1:8805
+  </Proxy>
+
+  RewriteEngine On
+
+  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} -d
+  RewriteRule ^(.+[^/])$ $1/ [R]
+
+  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} \.php
+  RewriteRule ^(.*)$ $1 [QSA,L]
+
+  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
+  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME}/index.html -f
+  RewriteRule ^(.*)$ $1/index.html [QSA,L]
+
+  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
+  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME}/index.php -f
+  RewriteRule ^(.*)$ $1/index.php [QSA,L]
+
+  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} -d
+  RewriteRule ^(.*)[^/]$ $1/ [QSA,L]
+
+  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
+  RewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L]
+
+  AddOutputFilterByType DEFLATE text/html
+  AddOutputFilterByType DEFLATE application/x-javascript
+  AddOutputFilterByType DEFLATE text/css
+  AddOutputFilterByType DEFLATE text/plain
+  AddOutputFilterByType DEFLATE text/xml
+  AddOutputFilterByType DEFLATE application/xml
+  AddOutputFilterByType DEFLATE application/xhtml+xml
+
+  BrowserMatch ^Mozilla/4 gzip-only-text/html
+  BrowserMatch ^Mozilla/4.0[678] no-gzip
+  BrowserMatch bMSIE !no-gzip !gzip-only-text/html
+
+  php_value include_path /path/to/my/app/php:/usr/local/lib/php:.
+  php_value auto_prepend_file /path/to/my/app/php/auto_prepend.php
+
+  # this not only blocks access to .svn directories, but makes it appear
+  # as though they aren't even there, not just that they are forbidden
+  <DirectoryMatch "^/.*/\.svn/">
+    ErrorDocument 403 /404.html
+    Order allow,deny
+    Deny from all
+    Satisfy All
+  </DirectoryMatch>
+
+</VirtualHost>
+</code></pre>
+
+Jens Kraemer reports this differing proxy setup that uses the P option in Rewrite rules so as not to use the ProxyPass directive:
+
+<pre><code>
+  # Don't do forward proxying
+   ProxyRequests Off
+
+   # Enable reverse proxying
+   <Proxy *>
+     Order deny,allow
+     Allow from all
+   </Proxy>
+
+   RewriteEngine On
+
+   # Check for maintenance file. Let apache load it if it exists
+   RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
+   RewriteRule . /system/maintenance.html [L]
+
+   # Rewrite index to check for static
+   RewriteRule ^/$ /index.html [QSA]
+
+   # Let apache serve static files (send everything via mod_proxy that
+   # is *no* static file (!-f)
+   RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
+   RewriteRule .* http://127.0.0.1:8200%{REQUEST_URI} [L,P,QSA]
+</code></pre>
+
+the P option to the last rule replaces the ProxyPass and
+ProxyPassReverse directives.
+
+
+h2. SVN Security
+
+If you use svn to issue checkouts instead of exports, you'll need to hide those pesky .svn directories.  This works:
+
+<pre><code>
+# this not only blocks access to .svn directories, but makes it appear
+  # as though they aren't even there, not just that they are forbidden
+  <DirectoryMatch "^/.*/\.svn/">
+    ErrorDocument 403 /404.html
+    Order allow,deny
+    Deny from all
+    Satisfy All
+  </DirectoryMatch>
+
+</VirtualHost>
+</code></pre>
+
+h2. Reading REMOTE_USER from mongrel through proxy
+
+Jon Reads reports successfully reading the REMOTE_USER variable:
+
+After many hours trying to solve the same problem I found this post: "Forcing a proxied host to generate REMOTE_USER":http://www.nabble.com/Forcing-a-proxied-host-to-generate-REMOTE_USER-tf1114364.html#a2914465
+
+and can confirm that the following works for me when put in the Proxy
+directive on Apache 2:
+
+<pre><code>
+   RewriteEngine On
+   RewriteCond %{LA-U:REMOTE_USER} (.+)
+   RewriteRule . - [E=RU:%1]
+   RequestHeader add X-Forwarded-User %{RU}e
+</code></pre>
+
+h2. References and Other Guides
+
+[1] "Time For A Grown-Up Server: Rails, Mongrel, Apache, Capistrano and You":http://blog.codahale.com/2006/06/19/time-for-a-grown-up-server-rails-mongrel-apache-capistrano-and-you/
+
+[2] "Bradley Taylor's Fluxura":http://fluxura.com/ and "RailsMachine":http://www.railsmachine.com/
+
+[3] "Slingshot Hosting Automated Capistrano Recipe":http://www.slingshothosting.com/support/capistrano
+
+Thanks to many users on the mongrel list for making it easy for me to compile all these tips and tricks as they come across the list.
+
diff --git a/site/src/docs/choosing_deployment.page b/site/src/docs/choosing_deployment.page
new file mode 100644
index 0000000..7a91e25
--- /dev/null
+++ b/site/src/docs/choosing_deployment.page
@@ -0,0 +1,178 @@
+---
+title: Choosing Deployment
+inMenu: false
+directoryName: Choosing Deployment
+---
+
+h1. Choosing The Best Deployment
+
+A major motivation for writing Mongrel was to make it easy to deploy Ruby web applications
+within existing infrastructures and organizations.  Most of the companies I tried to
+pitch "Ruby on Rails":http://www.rubyonrails.org/ to loved how fast and easy it was to develop,
+but ran screaming when I talked about FastCGI.
+
+Mongrel fixes this by just being a plain HTTP server that is still very fast.  It's easy to
+deploy, cluster, manage, and scale with existing web application technologies.  You can
+put it behind hardware load balancers, load balancing web servers, proxy servers, or just
+by itself.
+
+With this flexibility comes a bit of confusion though.  Many people start off wondering how best to
+deploy Mongrel and then get confused with all the different options available.  This document
+hopefully will help you pick the right deployment for your needs.  They are listed in order
+from smallest/simpler to largest/complex.
+
+h2. Deployment Considerations
+
+There are a few initial things you'll have to consider when picking a deployment:
+
+* Concurrency -- Rails is not thread safe, so if you have giant actions that take
+minutes to complete then take that into consideration.
+* Requests/Second -- Notice I didn't say "users"?  Users is a useless measurement of
+your performance requirements.  You want to know how many *requests per second* you have to process.
+* Content Size -- What's the size of the content you're serving.  Mongrel is pretty decent
+at static files, but it can't beat a good solid web server for pushing out big files.
+* Dynamic vs. Static -- Mongrel can serve static content for small sites, and of course do
+dynamic Ruby generated content, but you'll want to figure out what the mix is so you can scale it later.
+* Available Resources -- You can't cram a truck into a breadbox.  Make sure you have the right deployment
+for your resources such as memory, disk, CPU, etc.
+
+h3. Scalability Means Expansion Not Speed
+
+I'm not sure where the term "scalability" changed from it's original meaning, but you should
+throw out any notion of scalability meaning "high performance".  Scalability is about resources
+and how easy it is for you to expand those resources to meet new demand.  This does not mean
+how many resources you can buy now for *all* the demand you'll ever need.  It means the ability
+to start small now, and then *after* you're the next google you can expand.
+
+h3. Start Small
+
+Everyone immediately jumps to the end of this document and starts with the absolute most complex and
+"scalable" deployment they can muster.  What you really want to do is start with a very small and simple
+setup, and then expand as needed.  This mitigates the risk that you'll buy a bunch of stuff you really
+don't need and keeps your initial pain and costs low.
+
+h3. Automate, Automate, Automate
+
+You're a damn programmer.  You should be scripting the hell out of your deployment just like
+you do your testing.  Automation reduces human error, makes your setups consistent, and many
+times can become a project itself just like "Capistrano":http://manuals.rubyonrails.com/read/book/17
+did.
+
+h1. The Recommendations
+
+Once you've figured out all the basic things about your planned deployment you can start deciding
+which one you need at the moment, and what you might need in the future.
+
+Wait.  You did *plan* this deployment right?  Ok, go back and actually plan it.  This document
+is part of your planning, but you need to do your homework first to make a good decision.
+
+h2. Just Mongrel
+
+Mongrel is actually pretty fast even when compared with web servers like "Apache":http://httpd.apache.org/
+for serving static files.  If your web application is just starting out, doesn't need to coexist with
+things like PHP, and you don't need SSL, then consider just running Mongrel by itself.
+
+This is especially attractive if your application can utilize page caching.  Mongrel is pretty quick
+for page cached sites and is able to handle quite a few concurrent connections.
+
+h3. Disadvantages
+
+Mongrel will break down pretty quick if you have lots of people accessing Rails actions that are
+slow.  It can still perform like a champ for most small needs, but if you start getting more
+serious then you need one of the next solutions.
+
+h3. Advantages
+
+The easiest to manage, especially on win32.  You just turn it on and go home.  Maybe write a
+few /etc/init.d/ start-up scripts for your server if you're running a POSIX system.
+
+
+h2. Behind TCP Balancers
+
+You still don't need SSL, but you do need to make a small cluster of Mongrel servers.  If this
+is the case, then you can simply grab "mongrel_cluster":/docs/mongrel_cluster.html and either
+get "Pen":http://siag.nu/pen/ or "Balance":http://www.inlab.de/balance.html and do a simple
+cluster.
+
+h3. Advantages
+
+This configuration is very easy to setup, gives you decent throughput and concurrency, and is
+easy to manage.  Using mongrel_cluster gives you simple commands to control whole clusters of
+Mongrel servers and Pen or Balance simply accepts connections on one port and forwards them
+to one of the backend Mongrel ports.
+
+h3. Disadvantages
+
+No SSL and you're still relying on Mongrel to serve the files.  A cluster of Mongrel servers
+is no slouch though.  I think many sites that don't need SSL could run with this configuration
+happily for years.  A real good mix is to combine this with Rails' @asset server@ configuration
+and a simple "thttpd":http://www.acme.com/software/thttpd/ install to serve your static files.
+
+h2. Behind HTTP Balancers
+
+If you need something like the above, but you also need SSL, then simply swap out Balance or Pen
+and use "Pound":/docs/pound.html instead.  Pound is a very flexible HTTP balancer that
+also supports SSL.  This gives you the same advantages of simple deployment but adds the security
+you need.
+
+h3. Advantages
+
+The same as using a TCP balancer, except you now have SSL and you can do some more creative
+routing.  A good example is if your site has to use a PHP web app for serving ads.  You can
+have pound take requests for the advertising URIs and route them to the PHP application, and
+then transmit everything else to your Mongrels.  It's very flexible and much easier to install.
+
+h3. Disadvantages
+
+You're still relying on Mongrel to serve the files and passing that through Pound, but as
+mentioned before Mongrel is pretty quick with static files.  Don't underestimate it.
+
+h2. Behind Web Servers
+
+If you have complex static file serving needs, need to host a PHP application at the same time,
+or have complex authentication requirements, then you should use a regular web server.  Mongrel
+has good instructions for quite a few web servers and supports any server that has some form
+of @mod_proxy@ style support.
+
+* "Apache":/docs/apache.html
+* "Litespeed":/docs/litespeed.html
+* "Lighttpd":/docs/lighttpd.html  *not recommended*
+
+Each of the above documents describe how to get an initial configuration of Mongrel running behind
+that type of web server.  You should also combine this with "mongrel_cluster":/docs/mongrel_cluster.html
+to manage the cluster of mongrel servers.
+
+h3. Advantages
+
+Since you have a real web server handling the initial HTTP traffic you can easily do page caching
+and other magic to speed things up and avoid even talking to Mongrel.  It also means you can put
+in authenticators, other web platforms, and extensions that your application might need.  Many
+web servers are also installed and configured by default on most platforms and you just need
+to add the Mongrel specifics to get it going.
+
+h3. Disadvantages
+
+This configuration can quickly descend into madness with complexity.  Apache is
+notorious for having a horribly complex configuration file.  Another
+disadvantage of real web servers is they almost always start of as web servers,
+and then proxy support is bolted on as an extra.  Apache's latest proxy support is
+really good as well as Litespeed's, but Lighttpd's proxy support is really bad (as of Mongrel 0.3.13).
+
+
+h2. Behind Hardware
+
+If you are getting really really serious about your web application and you need to
+serve up lots of Mongrels then you should take a look at a hardware load balancer.
+They're really expensive, but they're usually worth it if you're in the big leagues.
+
+h3. Advantages
+
+Big big big loads and the ability to handle the SSL in hardware for many products.
+Also things like smart virus filtering, routing and other goodies, but you'll
+pay for it.
+
+h3. Disadvantages
+
+Expensive, Expensive, Expensive.  Did I mention Expensive.  One more time Expensive.
+They're also a royal pain to setup properly, but then that's why their Expensive.
+
diff --git a/site/src/docs/contrib.page b/site/src/docs/contrib.page
new file mode 100644
index 0000000..6f3c6c1
--- /dev/null
+++ b/site/src/docs/contrib.page
@@ -0,0 +1,199 @@
+---
+title: Contribute
+inMenu: true
+directoryName: Contribute
+---
+
+h1. Contributing To The Mongrel Canon
+
+The documentation for Mongrel is typically written by me (Zed), but other
+people have contributed lots of blog articles about Mongrel, actual site
+documentation, or reviews and enhancements.  It's pretty easy to contribute
+documentation to the Mongrel canon, although what gets in is strictly
+controlled in order to make sure the information quality is high.
+
+We are always looking for grammar and spelling freaks to send in suggestions,
+and anyone who has done a difficult deployment to post their experiences to
+the mailing list.  Typically if your experiences get a positive response
+then you may be asked to write up some documentation on it for the canon.
+
+
+h2. What We Need
+
+The Mongrel project strives to be simple to use so that people don't
+necessarily need to read many wizardly tomes to get started.  Once people have
+Mongrel figured out they typically want to do advanced things like deploy their
+application in a well configured production setting or extend it.
+
+With that in mind, we are not really looking for introductory documentation
+unless it is in languages other than English.  The initial getting started for
+Mongrel is pretty thin because it is so simple.
+
+Also, the code for Mongrel is well documented and constantly updated as work is
+done.  If you find errors in the "Mongrel RDoc":/rdoc/index.html then tell the
+"mailing list":http://rubyforge.org/mailman/listinfo/mongrel-users and it'll
+get fixed right up.
+
+What we are looking for is anything that's blank on the main
+"documentation":/docs/index.html page and anything that is suitable for the FAQ
+or a quick tip or trick.
+
+When writing your documentation make sure you keep it very short and you focus
+on the details people need to get something working.  The end results should be
+functioning, but maybe not a complete massive google capable cluster.  A really
+good model to follow is the "cut-and-paste HOWTO".  In this style of
+documentation it's assumed that people will simple select the commands they
+have to type and it will work.
+
+Finally, do not focus on system specific issues such as Debian install, RedHat
+package management, setting up MySQL, etc.  These topics are really needed, but
+they don't fit in with documentation on Mongrel.  What you can do is place a
+statement that lists what people should already have configured prior to
+starting the instructions, especially referencing other instructions they
+should read.
+
+
+h2. Getting Credit
+
+A cornerstone of the Mongrel project is that everyone deserves credit for the
+free work they do.  There's an "attributions":/attributions.html page that I
+try to use to list people who've contributed work, cash, coffee, comments, etc.
+Sometimes people get dropped, but if you think you were missed then say
+something.  It's important that people who work for free get recognized for
+their contributions.
+
+When you write your documentation, feel free to add a by-line at the top and
+link to your blog.  Keep in mind that "RubyForge":http://www.rubyforge.org/
+doesn't like people linking to commercial entities, but personal blogs or other
+open source projects are just fine.  If your boss sponsored the time for you to
+develop the documentation and contribute it, then feel free to mention their
+name in the documentation and say thanks.
+
+h2. Avoid "Works-For-Me Syndrome"
+
+A very, very important thing to strive for is that people can take your
+documentation, and with a good knowledge of their own system, can get through
+the instructions with minimal difficulty.  Systems change, so you may have to
+keep track of the latest releases of packages and how your instructions might
+need an update.
+
+What you *don't* want to do is slam out some half-assed set of instructions
+that really only work on your little custo-hacked Debian/RedHat frankenstack.
+It's a really good idea to try your instructions out on a fresh machine using a
+different flavor of Linux or Unix just to make sure that you didn't miss
+anything.
+
+h1. Writing The Documentation
+
+Now that you've got something to say, it's time to go through the trouble of
+saying it.  You should read through the documentation that is currently written
+and see if you can get the same flavor.  Feel free to be quirky and write in
+your own style, just make sure the instructions are good.
+
+To start writing you're going to need a few tools and to dip into subversion
+land for a few seconds.
+
+h2. Installing Webgen And Friends
+
+The site is actually generated from static files that use
+"webgen":http://webgen.rubyforge.org/ to generate the site.  The contents are
+"Textile":http://textism.com/tools/textile/ and you can use the "hobix textile
+reference":http://hobix.com/textile/ to guide you.
+
+To install webgen do the following:
+
+ gem install webgen bluecloth redcloth
+
+The install may complain that you need other gems installed, so feel free to
+install those as well.  You typically don't need them since you're just gonna
+generate the site from the source so you can confirm that what you're writing
+fits.
+
+You should also make sure that you have
+"subversion":http://subversion.tigris.org/ and/or "svk":http://svk.elixus.org/
+installed.  These instructions will use subversion.
+
+You may also want to install Rake and any tools your operating system needs to
+build Mongrel itself, just in case you want to have a full build.  This isn't
+needed for writing documentation though.
+
+h2. Getting The Site
+
+You now just need to grab the source from the anonymous subversion repository:
+
+ svn checkout svn://rubyforge.org/var/svn/mongrel mongrel
+
+People using svk can do this with:
+
+ svk mirror svn://rubyforge.org/var/svn/mongrel //mirror/mongrel
+
+And then use the normal svk commands to check it out:
+
+ svk checkout //mirror/mongrel mongrel
+
+You should probably make sure you're in some kind of *projects* directory so
+that you don't have a bunch of garbage lying around.  Keep in mind also that
+svk is sensitive to you moving this directory--you have to "detach" it first.
+
+h2. Writing or Editing Your Page
+
+The Mongrel web site is held in the @doc/site@ directory.  In this directory
+there's a @src/docs@ directory where most of the documentation is kept.
+
+What you have to do is find the page you are going to edit it, and open it in
+your "favorite editor":http://vim.sourceforge.net/ to go to work.  You'll want
+to make sure you have a preamble like this on any new pages:
+
+<pre>
+<code>
+ ---
+ title: OneWordMenuTitle
+ inMenu: true
+ directoryName: MyTitle
+ ---
+</code>
+</pre>
+
+@MyTitle@ can be pretty much any length, but I typically have it match the one
+word title.  The @OneWordMenuTitle@ will show up in the left hand navigation
+menu, unless you set @inMenu@ to @false@.
+
+With that done, just use the "hobix textile
+reference":http://hobix.com/textile/ and write your documentation.
+
+h2. Reviewing Before Submitting
+
+Reviewing your documentation requires that you simply run @webgen@ and then
+look at the resulting .html page in your browser of choice.  Some important
+formatting issues to watch for are:
+
+* Make sure that you put &lt;pre&gt;&lt;code&gt;...&lt;/code&gt;&lt;/pre&gt; around code sections or use the textile syntax.
+* Make sure that code sections you have are not too wide since the site has a fixed width
+main section.
+* You can include images if you think a diagram will make more sense.
+* Use section heading to break up the instructions into discrete pieces.
+
+h2. Submitting Your Documentation
+
+The easiest way to submit changes to the documentation is to simple send me
+(zedshaw AT zedshaw dot com) the page and I'll put it up after reviewing it.
+If you have your own web site then you can also put the page on there
+temporarily.
+
+When you have several changes to multiple documents then you'll need to
+generate a patch and send that in.  With svk you'll use the @svk patch@ command
+and then mail me the results.  With subversion you should be able to just do
+@svn diff@ and I'll be able to use it.
+
+Make sure when you generate patches that you aren't including changes to the
+Mongrel source (unless that's your intent).  It's better to hand in site and
+code patches separately.
+
+
+h1. Getting And Giving Credit
+
+Don't forget that you deserve credit for working on this document, but that you
+also need to reference sources you read while writing it.  Put you name at the
+top as the author, and then list at the bottom other documents you referenced
+or people who helped you.
+
diff --git a/site/src/docs/debian-sarge.page b/site/src/docs/debian-sarge.page
new file mode 100644
index 0000000..56ae075
--- /dev/null
+++ b/site/src/docs/debian-sarge.page
@@ -0,0 +1,289 @@
+---
+title: Debian HOWTO
+inMenu: true
+useERB: false
+directoryName: Documentation
+---
+
+h1.  Debian
+
+h3.  By Chris McGrath
+
+There's been issues with people installing on Debian, so this document is an
+attempt to detail how to do it. There are actually three different ways (at
+least! You may find more). The easy way worked first time I attempted it on
+a new VPS I was installing. The frankinstall way was discovered when I
+attempted to recreate the easy way to test the process on a brand new local
+Debian install. The backport your own way was worked out to avoid the
+frankinstall you end up with using the second method.
+
+h2. How to find out which one you need
+
+Debian 3.1 only has Ruby 1.8.2, so you'll need to get Ruby 1.8.4 which is in testing. So
+add the following to your /etc/apt/sources.list.
+
+<pre>
+  <code>
+    deb ftp://ftp.uk.debian.org/debian/ testing main
+  </code>
+</pre>
+
+*Make sure and change the .uk. to your local mirror.*
+
+Now pin the testing repo so you don't install stuff from it accidentally.
+You'll need to edit /etc/apt/preferences, which doesn't exist on a bare install
+so create it and add the following three lines:
+
+<pre>
+  <code>
+    Package: *
+    Pin: release a=testing
+    Pin-Priority: 200
+  </code>
+</pre>
+
+OK, now to find out whether you're a lucky bunny or you have displeased your
+personal favorite deity. As root do:
+
+<pre>
+  <code>
+    root# apt-get update
+    root# apt-get -s -t testing install ruby irb rdoc ri ruby1.8-dev \
+          libzlib-ruby libopenssl-ruby1.8
+    
+  </code>
+</pre>
+
+*Notice the -s it's important*
+
+Examine the output, if you see the following:
+
+<pre>
+  <code>
+    The following packages will be REMOVED:
+      base-config initrd-tools kernel-image-2.6.8-2-386
+  </code>
+</pre>
+
+Then you're one of the unlucky ones, sorry. Skip to the backport way
+(preferred) or if you're feeling brave the frankinstall way.
+
+h2. Installing the basic stack
+
+If your still reading, congratulations! You don't have kernel issues and you
+should be up and running pretty quickly.
+
+h3. Ruby
+
+First actually install Ruby, so as root do:
+
+<pre>
+  <code>
+    root# apt-get -t testing install ruby irb rdoc ri ruby1.8-dev \
+          libzlib-ruby libopenssl-ruby1.8
+  </code>
+</pre>
+
+h3. RubyGems
+
+Debian don't provide packages for RubyGems, so we have to get it from somewhere
+else. A kind soul has made debs for RubyGems 0.8.11 available, so add the
+following to your /etc/apt/sources.list
+
+<pre>
+  <code>
+    deb http://www.sgtpepper.net/hyspro/deb unstable/
+  </code>
+</pre>
+
+The final / is important. To install RubyGems do:
+
+<pre>
+  <code>
+    root# apt-get update
+    root# apt-get install rubygems
+  </code>
+</pre>
+
+This package doesn't copy gem files to /usr/bin, instead it puts them in
+/var/lib/gems/1.8/bin so we need to add that to the path. Edit /etc/profile and
+add <code>:/var/lib/gems/1.8/bin</code> to the end of each PATH statement,
+there's one for root and one for other users in the standard Debian
+install. You'll need to log in and out again to get your path setup
+correctly.
+
+(NOTE: Some people say just install rubygems from source if this doesn't work
+for you).
+
+h3. GCC & Friends
+
+We're nearly ready to install Mongrel, if you're doing a frankinstall go back
+to that page for the details. For the rest of us, the command is:
+
+<pre>
+  <code>
+    root# apt-get install build-essential
+  </code>
+</pre>
+
+h3. Rails & Mongrel
+
+Time to install Rails and Mongrel at last!
+
+<pre>
+  <code>
+    root# gem install rails --include-dependencies
+    root# gem install mongrel mongrel_cluster --include-dependencies
+  </code>
+</pre>
+
+Pick the latest ruby version of Mongrel from the menu. Wait for it to finish. *CONGRATULATIONS*
+
+h3. Testing
+
+To make sure the congratulations weren't premature, lets check it works. Login
+as a normal user and do:
+
+<pre>
+  <code>
+    user$ rails test_app
+    user$ cd test_app
+    user$ script/generate controller HelloWorld index
+  </code>
+</pre>
+
+Edit <code>app/views/hello_world/index.rhtml</code> to look like:
+
+<pre>
+  <code>
+    <h1>Hello World</h1>
+    <p><%= Time.now.to_s(:long) %></p>
+  </code>
+</pre>
+
+Lets check it's all running.
+
+<pre>
+  <code>
+    user$ mongrel_rails start
+  </code>
+</pre>
+
+Point your browser at http://999.999.999.999:3000/hello_world
+
+(NOTE: Replace 999.999.999.999 with your IP address.)
+
+h1. Backporting 1.8.4 from testing
+
+Sorry you're here, but hey lets get this done. This involves building your own
+debs for Ruby 1.8.4 from source, so you don't have to upgrade your kernel and
+install the build tools from testing like in the frankinstall.
+
+h2. Building your own Ruby debs
+
+First up, you need to *remove* the line we added before in
+/etc/apt/sources.list and clear out /etc/apt/preferences, so do that now. We're
+going to get the source from testing, so add the following to
+/etc/apt/sources.list
+
+<pre>
+  <code>
+    deb-src ftp://ftp.uk.debian.org/debian testing main
+  </code>
+</pre>
+
+*Make sure and change the .uk. to your local mirror.*
+
+And do the following as root:
+
+<pre>
+  <code>
+    root# apt-get update
+    root# apt-get install devscripts # if you don't have them already
+    root# mkdir scratch
+    root# cd scratch
+    root# apt-get source ruby1.8
+    root# apt-get build-dep ruby1.8
+    root# cd ruby1.8-1.8.4
+    root# debuild -us -uc
+    root# cd ..
+    root# rm ruby1.8-elisp # unless of course you've emacs installed
+    root# dpkg -i *.deb
+    root# ln -s /usr/bin/ruby1.8 /usr/bin/ruby
+    root# ln -s /usr/bin/irb1.8 /usr/bin/irb
+    root# ln -s /usr/bin/ri1.8 /usr/bin/ri
+    root# ln -s /usr/bin/rdoc1.8 /usr/bin/rdoc
+  </code>
+</pre>
+
+
+h3. To be worked out:
+
+* No libzlib-ruby deb made... couldn't figure out how to get it done
+* Install rubygems - when I ignored that and tried to use Ezra's sgtpepper.net mirror it wants to install ruby-1.8.2
+
+
+h1. Frankinstall of Mongrel on Debian Sarge
+
+If you're here I'm really, really sorry. I hope this doesn't mess up your
+machine. If you're going to do this I'd consider just using testing itself, or
+Ubuntu or something. Anyways, it's here for completeness, I had to re-install
+Debian four times to figure this out so I'm damn well writing it up.
+
+This details how to go from a basic debian-31r2-i386-netinst.iso install to
+having Ruby 1.8.4, RubyGems, Rails and Mongrel running (and a good part of
+testing). I'm not going to cover MySQL or any of that, this is purely about
+the dog.
+
+When I say a basic install, I mean a basic install. I entered linux26 at the
+boot menu to get a 2.6 based system. Let it do it's stuff, then when the
+installer asks what kind of system you want I chose to manual package
+selection, and only installed ssh.
+
+I'm going to assume you got as far as adding the testing stuff to
+/etc/apt/sources.list and /etc/apt/preferences from the Debian HOWTO page. The
+next thing you need to read is
+"this":http://www200.pair.com/mecham/spam/kernel.html, which explains why we
+have to do what we now have to do.
+
+h3. Upgrading the kernel
+
+<pre>
+  <code>
+    root# apt-get -t testing install initrd-tools
+  </code>
+</pre>
+
+This installed 0.1.84.1, so next time to install an updated kernel that can handle udev.
+
+<pre>
+  <code>
+    root# apt-get -t testing install linux-image-486
+  </code>
+</pre>
+
+Lots of stuff gets installed, including a 2.6.15 kernel. It asks you if you
+want to upgrade glibc during this so say yes. When it's finished, reboot the
+system.
+
+When it comes back up (and lets hope it does), time to install Ruby. Now you've
+upgraded the kernel this is the same procedure the lucky people get to use. So
+go and follow the instructions for Ruby and RubyGems there, then come back here
+when it's time for GCC and it's toolchain.
+
+h3. Installing the testing version of the GCC toolchain
+
+Because of glibc issues now you've upgraded your kernel, you're back here. It's
+actually not that different a command from the lucky people, it just installs a
+bunch more stuff from testing than you might be comfortable with.
+
+<pre>
+  <code>
+    root# apt-get -t testing install build-essential
+  </code>
+</pre>
+
+When it's finished, and you have your frankinstall, it's time to install Rails
+and Mongrel at last! Back to the luck people page, it's the same from here on
+in. Good luck! I don't guarantee you'll have a trouble free ride installing
+whatever else you need to get going, but I hope you do.
diff --git a/site/src/docs/distributed_worker.page b/site/src/docs/distributed_worker.page
new file mode 100644
index 0000000..a74913e
--- /dev/null
+++ b/site/src/docs/distributed_worker.page
@@ -0,0 +1,105 @@
+---
+title: Offloading
+inMenu: true
+directoryName: Offloading
+---
+
+h1. Long Tasks For Slow Rails
+
+You've got the best idea ever for a web site.  It's a fantastic
+Franken-stack that takes requests from the internet, converts them
+to giant PDFs with latex, puts them onto 20 FTP servers, and then
+encrypts them using 2^718 bit Eliptic Curve Encryption.
+
+Best of all, in order to avoid a "single point of failure" you've
+decided that all this monstrous Rube Goldberg Architecture needs to
+be run via a series of IO.popen calls to various Perl scripts.
+
+
+h2. How Bad Ideas Begin
+
+Yes, this is contrived but not by much.  I've actually had people report
+architectures very close to this with pride.  I have no idea why
+making something complex suddenly makes it smart, but oh well, I just work
+here.  You do what you want, but hear me out for a second before you
+continue down this path.
+
+Designs like this go very wrong very quickly for three main reasons:
+
+* Complex things are more fragile than simple things.  Your application is going
+down the same road as the Roman Empire, and just like them you don't realize it.
+* Systems with large numbers of interconnections are slower simply because
+everything takes time and more interconnections means more time to complete a process.  
+This isn't always the case, but given two systems that do the same work, I'll
+take the simpler less connected version since I know I can make that faster.
+* Complex things do not change easily, which feeds into their fragile nature and
+means they can't improve in performance.
+
+An excellent example of the above three conditions is this wonderfully hilarious
+"stack trace":http://ptrthomas.wordpress.com/2006/06/06/java-call-stack-from-http-upto-jdbc-as-a-picture/ (and the comments to back it up).  Somehow it doesn't dawn on the author
+that his "Business Logic" box is pointing at one line.  The comments are full
+of statements that support this type of design, but I bet half this crap isn't
+really necessary.  *This* my friends is the classic Rube Goldberg Architecture.
+
+Your Ruby brain is laughing at this, and now you want to do the exact same
+thing?  Start laughing at yourself my friend because you're next.
+
+
+h2. Down With Complexity
+
+Before you start offloading tons of work to external programs and designing your
+Franken-stack, step back and ask this very simple question:
+
+ "How could I do the same thing with less stuff?"
+
+Your goal for the next two hours is to remove anything that can be done
+simpler, isn't needed, or just simply adds overhead.  You want to ignore
+that voice in your head screaming, "*But how will you get a job!?*"  Yell
+back at it, "*I have a job!*"  And then do your job.  Create a system that
+does what it's supposed to with the least amount of resources.  No more, no
+less.  If you need to add something, add it later.  Right now an 80% solution
+that works is better than a 99% solution that's out 6 years from now.
+
+
+h1. The Distributed Worker Pattern
+
+You've simplified your Rube Goldberg Architecture down to the bare minimum
+and you've thought of simpler ways to do your processing, but you *still*
+have to call an external program.  There's no way to turn this program into
+a server, and the program takes a long time to run.
+
+Whatever you do, don't use IO.popen() to run it.  Don't use exec.  Nothing.
+People think that calling these functions to run an external program suspends
+the current Rails request while the external program runs.  That's right.  What's
+wrong is that it *suspends every other request as well*.  Mongrel will still accept
+connections and happily queue them all up, but it waits for Rails to exit this
+request before it gives it the next one.
+
+What you *need* to do is give this request to a special server called a
+"Distributed Worker".  This is a simple pattern where you hand something
+that takes forever to a server that knows how to do two things:
+
+# Run the request to produce a result.
+# Report status to the requester when asked.
+
+The typical scenario for using a Distributed Worker is something like this:
+
+# You have a Rails server and a Worker server running.  They talk using DRb.
+# Request comes into Rails, and an action builds the information needed by the Worker.
+# Rails submits the request to the Worker and takes a ticket.  It stuffs this into the user's
+session and then sends them to a "status action".
+# The Worker begins working on the request identified by the ticket.
+# At periodic intervals (probably with JavaScript) the client hits the status action which
+in turn takes the ticket and asks the Worker for status.
+# When the Worker is done it tells the status action in one of the status responses and
+the status action goes to a "collector action" that picks up the results using the ticket.
+# Finally, the collector gets the result from the worker and presents it to users.
+
+If you're smart, you can actually have all this going on in the "background" of the
+user interface in such a way that the user just sees requests queue up and slowly change
+state until they are done.
+
+The particulars of actually implementing this pattern are left to you, since
+the idea is that it's probably different for everyone.  There is one project
+though that makes this whole process generic and fairly easy called
+"BackrounDRb":http://backgroundrb.rubyforge.org/ thanks to Ezra Zygmuntowicz.
diff --git a/site/src/docs/frameworks.page b/site/src/docs/frameworks.page
new file mode 100644
index 0000000..7a55edb
--- /dev/null
+++ b/site/src/docs/frameworks.page
@@ -0,0 +1,34 @@
+---
+title: Frameworks
+inMenu: true
+directoryName: Frameworks
+---
+
+h1. Framework Issues
+
+As known issues specific to different frameworks are reported they get
+posted here.  Problems reported here aren't a sign that a framework is
+worse or better than others, just a reflection of people's experiences.
+
+h2. Rails
+
+* Rails is not thread safe so if you have long running actions then you can potentially
+block the server.  Keep in mind that this is the case for *any* server, it's just more
+pronounced for Rails.
+* You can easily kill a Rails server by not closing files.  Always open files in blocks.
+* If you turn on @allow_concurrency@ them Mongrel will run your application without any thread locking.
+This can be dangerous so test it first, and I'm pretty sure it won't work for most complex applications.
+* Mongrel will honor a HUP request and try to do an internal reload, but this usually doesn't work the
+way you think.  Mongrel's shutdown process is very nice and safe, so just restart.
+
+
+h2. Camping
+
+* Running Camping and Rails in the same Ruby interpreter
+causes all sorts of problems with ActiveRecord. You either run one or the
+other but not both.
+
+
+h2. Nitro
+
+* None reported yet.
diff --git a/site/src/docs/gem_plugin.page b/site/src/docs/gem_plugin.page
new file mode 100644
index 0000000..0e2ec96
--- /dev/null
+++ b/site/src/docs/gem_plugin.page
@@ -0,0 +1,335 @@
+---
+title: Writing Plugins
+inMenu: true
+directoryName: Documentation
+---
+
+* Jun 16: These docs are out of date and will be updated soon. *
+
+h1. Writing Mongrel Plugins with GemPlugin
+
+Mongrel uses a system called "GemPlugin":http://mongrel.rubyforge.org/gem_plugin_rdoc
+to let people create simple "RubyGems":http://rubyforge.org/projects/rubygems/
+extensions that get loaded dynamically when Mongrel starts.  This help document
+is more for experienced Ruby developers interested in extending Mongrel with
+new commands.
+
+*NOTE:* You can currently only write new commands
+such as "mongrel_rails dostuff".  Handlers and
+Filters are on their way.
+
+h2.  Why Plugins for Mongrel?
+
+If you've ever used other systems that have plugins you'll find there are
+several painful parts to writing your own plugin:
+
+* You don't have their developer tools so it takes forever to get started.
+* You don't know how to structure the project or even where to start.
+* Once you get it built you have to figure out how to register and install it.
+* When you want to update it you have to somehow get the update out to users.
+* You have to manage dependencies between your plugin and other plugins.
+* Including and using your own resources (images, html files, etc.) or config files
+  is really painful.  Not sure why this is but it's really annoying.
+
+Most people solve many of the problems by the "sourdough method".  They
+take a plugin that currently works, copy it, and base their plugin
+on the prototype.  This works great until you want to do something
+original or until you find out the original author did something wrong.
+
+GemPlugin solves this problem by relying on the regular RubyGems
+package management system to give you:
+
+* A simple way to package, distribute, manage, and update your Mongrel plugins.
+* Dynamic loading based on the gem dependencies and not on specific configurations.
+* Segregated extensions for Mongrel.
+* All the capabilities of RubyGems.  GemPlugin doesn't mess with them at all.
+* A little generator that starts your project off right similar to how Rails generators work.
+* The ability to package resources (images, configs, etc.) with your gem and then load them
+  dynamically no matter where the gem eventually gets installed.
+
+In the end GemPlugins are just RubyGems that get loaded a special way
+so they are activated right away.  The only extra thing is a bit of
+"magic" that puts plugins into a nice little namespace outside of
+the usual Ruby module and class hierarchy.
+
+The advantage for Mongrel is that people can write their own
+plugins and distribute them easily without anything more complex
+than what all Ruby developers already have:  RubyGems.
+
+h2.  How They Work
+
+Mongrel plugins (a.k.a. GemPlugins) are really very simple.  Basically
+when you use the GemPlugin API you tell it what kind of dependencies
+will trigger a gem to be loaded.  GemPlugin then goes through all of
+the installed gems and loads any that meet the dependency description.
+Then your plugin just registers itself in the right "plugin category"
+and everything starts working.  The user of your plugin won't have to
+do too much unless you want to give them additional configuration.
+
+The best way to understand this is to actually build a plugin
+and watch it work.
+
+
+h2.  Your First Plugin
+
+Make sure that you have rubygems, mongrel, gem_plugins, and
+rake all installed and working right.
+
+Yes, this means that you are forced to use RubyGems.   People who really don't
+like RubyGems are free to take the core of the Mongrel Server API and re-use it
+as they wish.  Just using Mongrel doesn't require this return so feel free to
+use it like crazy in your commercial software or other licensed project.
+
+Once you have all that installed you need to simply find a nice quiet
+place to generate your initial plugin directory with the *gpgen*
+command:
+
+ $ gpgen myplugin
+
+Let's say we're going to reimplement the existing mongrel_status example
+command which just prints out the PID of a running Mongrel server
+on any POSIX system.  (Win32 folks will have to play along).  
+
+Just do the following:
+
+ $ gpgen mongrel_status
+ Creating directory mongrel_status
+ Creating file mongrel_status/COPYING
+ Creating directory mongrel_status/lib
+ Creating file mongrel_status/LICENSE
+ Creating file mongrel_status/Rakefile
+ Creating file mongrel_status/README
+ Creating directory mongrel_status/resources
+ Creating directory mongrel_status/tools
+ Creating directory mongrel_status/lib/project
+ Creating file mongrel_status/lib/project/init.rb
+ Creating file mongrel_status/resources/defaults.yaml
+ Creating file mongrel_status/tools/rakehelp.rb
+ Creating proper 'mongrel_status/lib/mongrel_status/init.rb' file
+
+This creates the skeleton of your plugin project.  There's not too many
+files in here, but let's cover what each one does:
+
+* *mongrel_status/COPYING* -- Your license or copying restrictions.
+* mongrel_status/lib -- Where you store your source for the plugin to use.
+* *mongrel_status/LICENSE* -- Your license again.
+* *mongrel_status/Rakefile*  -- Builds your stuff.
+* *mongrel_status/README* -- Instructions for using your plugin.
+* mongrel_status/resources -- A place to put files your plugin might need.
+* mongrel_status/tools -- Tools used by rake.
+* mongrel_status/lib/mongrel_status -- Your init.rb goes here.
+* *mongrel_status/lib/mongrel_status/init.rb* -- Required to initialize your plugin.
+* mongrel_status/resources/defaults.yaml -- Default configuration options.
+* mongrel_status/tools/rakehelp.rb -- Used by the Rakefile.
+
+The files in bold are the ones you're going to have to edit to create your
+plugin.
+
+
+h2.  COPYING, LICENSE, and README
+
+At first you can probably just skip these, but when you go to
+distribute your plugin you'll need to make sure that you have
+some kind of license on it and some basic instructions for
+people to read.
+
+Check "OSI":http://www.opensource.org/ for a list of some available licenses.
+
+
+h2. Rakefile
+
+This is the first place you need to go in order to setup your Mongrel command
+correctly as a Mongrel plugin.  The file is pretty small, but if you're
+not familiar with Rake syntax you can "read the Rake docs":http://rake.rubyforge.org/
+for more advanced help.
+
+To get you started though, here's what you have to change:
+
+Change the version from 'version="0.1"' to whatever you want.
+
+Go the setup_gem block and add mongrel as a dependency, set yourself as the author, and change the summary:
+
+ setup_gem(name, version) do |spec|
+   spec.summary = "The mongrel_status GemPlugin"  ## change this
+   spec.description = spec.summary
+   spec.author="Nobody"  ## change this
+   spec.add_dependency('gem_plugin', '>= 0.2')
+   spec.add_dependency('mongrel', '>= 0.3.10')  ## add this
+   spec.files += Dir.glob("resources/**/*")
+ end
+
+That's it for the Rakefile.  It won't do much since you still have to setup the actual command
+in the mongrel_status/lib/mongrel_status/init.rb file, but you could build this right now
+and install it:
+
+  $ rake
+  $ gem install pkg/mongrel_status-0.1.gem
+  
+Not so glamorous yet you'll get there soon.  
+
+*You might need to do 'gem uninstall mongrel_status' if you installed that already.*
+
+
+h2. lib/mongrel_status/init.rb
+
+This is where the magic really start to happen.  In this file is just a
+little nothing class you need to edit in order to get everything working
+right.  Here's the contents that you should have:
+
+ require 'gem_plugin'
+ class ChangeME < GemPlugin::Plugin "/somecategory"
+ end
+
+You'll want to change this file to be the following:
+
+ require 'gem_plugin'
+ require 'mongrel'
+ class Status < GemPlugin::Plugin "/commands"
+    include Mongrel::Command::Base
+ end
+
+This doesn't quite do anything useful as a command yet, but now if we
+remove the gem and rebuild we'll be able to see *mongrel_rails* list
+the command as being available:
+
+ $ gem uninstall mongrel_status
+ $ rake
+ $ gem install pkg/mongrel_status-0.1.gem
+ $ mongrel_rails
+ Available commands are:
+  
+   - restart
+   - start
+   - status
+   - stop
+  
+  Each command takes -h as an option to get help.
+  $
+
+See how your list of available commands now has "status" listed?
+Try doing 'gem uninstall mongrel_status' and run *mongrel_rails*
+again to see the command go away.  Keep doing this until the
+magic wears off.
+
+
+h2.  Explaining the PFM
+
+How the hell does GemPlugin do that?  I mean, you just tweaked a
+Rakefile and made a class and *somehow* mongrel_rails gets
+a brand new command without you ever touching Mongrel.  Magic
+right?  No, PFM.
+
+Here's how all of this works (for the engineers who can't use
+something until they've analysed it's complete chemical composition):
+
+# Your gem has two dependencies:  gem_plugin and mongrel.
+# Your gem also has a file lib/mongrel_status/init.rb
+# This init.rb file has 'class Status < GemPlugin::Plugin "/commands"'
+   which registers it as a Plugin at the "/commands" category.
+# When *mongrel_rails* starts it tells GemPlugin to load all the plugins (gems)
+   that depend on both gem_plugin and mongrel (but not rails).
+# The GemPlugin system then goes through all the installed gems and simply
+   does a require on the init.rb when it finds a gem with the right dependencies.
+# Since your gem depends on the right stuff, and has a lib/mongrel_status/init.rb
+   it gets loaded properly and *mongrel_rails* can list it.
+# The only remaining magic is the Status class is loaded by init.rb and that
+   puts it into the /commands category of plugins.  Mongrel rails considers
+   and plugin in this category to be a valid Mongrel command.
+
+What happens in someone else puts a Plugin in the /commands category?  Well,
+since *mongrel_rails* is only loading gems which depend on *both* gem_plugin
+and *mongrel* then there's no problems.  You Snafu project can be safe knowing
+it's /commands won't get loaded.
+
+An additional piece of magic is that *mongrel_rails* holds off on loading
+and GemPlugin that depends on gem_plugin, mongrel, *and* rails.  These
+plugins are intended to be rails specific extensions or other things
+that you want Mongrel to have, but only *after* Rails is loaded and configured.
+
+What the above paragraph means is that, yes, you can actually distribute plugins
+for Rails using the Mongrel GemPlugins without having to go through the usual
+Rails plugin system.  This isn't tested yet, but feel free to try it out.
+
+
+h2.  The Final Touches
+
+The only thing that would be left is to actually implement the full
+mongrel_status command.  Rather than put the code into this document,
+you can just read what's in the
+"Subversion repository":http://rubyforge.org/plugins/scmsvn/viewcvs.php/*checkout*/trunk/projects/mongrel_status/lib/mongrel_status/init.rb?root=mongrel&rev=91
+and put that into your own init.rb.
+
+What the code there does is first sets up the command line options available,
+then validates them, and finally just runs the command in order to do it.  
+The code should be easy to follow but let me know.
+
+h3. A Note On Modules
+
+If you want you can put your plugin into a module and then it will be registered
+under "/commands/modname::cmdname".  So you did this:
+
+ require 'gem_plugin'
+ require 'mongrel'
+ module Examples
+   class Status < GemPlugin::Plugin "/commands"
+      include Mongrel::Command::Base
+   end
+ end
+
+Then the command would show up from mongrel_rails as "examples::status" and
+would be known as "/commands/examples::status".
+
+
+h2.  Big Tricks With GemPlugin
+
+"GemPlugin":http://mongrel.rubyforge.org/gem_plugin_rdoc/ has a couple of other
+methods that will really help you when writing a plugin that needs to have
+some default configurations or possibly have external data resources.  
+
+The first is the GemPlugin::Manager.instance.resource method.  What this method
+does is when given a gem and a path, it find the actual path to that resource
+in the installed gem directory.  These resources are packaged up out of your resources/
+directory in your plugin source.
+
+Using the current example if I wanted to get to the mongrel_status/resources/defaults.yaml
+file I'd do:
+
+ defaults = GemPlugin::Manager.instance.resource "mongrel_status" "/defaults.yaml"
+
+And then try to load that as a YAML file.  The *resource* method returns nil if
+no such file exists for the given plugin, and the plugin has to be loaded first.
+
+The problem with doing this for something like default configuration options is
+that you'll end up writing a ton of the same code for all your plugins.  To help
+with this, GemPlugin also has a *config* method which takes a set of options, and
+then tries to load the *resources/defaults.yaml* file as a set of defaults (modified
+by the options).
+
+Let's say you want to default to having debug off, but allow the user to pass in some
+options to turn it on.  This is how you'd do it:
+
+ options = GemPlugin::Manager.instance.resource "mongrel_status", user_ops
+
+What this does is simply use the *resource* method to locate and load the resources/defaults.yaml
+file, and then merge the *user_ops* hash into them so *user_ops* override the defaults.
+
+The point of these two pieces of functionality is that now you can completely package
+all the external resources your plugin needs and access it without much user
+intervention.  It would be a good idea to let the user override these paths.
+
+
+h2.  Rails Plugins Without Rails Plugins
+
+Ruby on Rails already has "an extensive set of plugins":http://wiki.rubyonrails.org/rails/pages/Plugins
+that you can choose from to make your application.  One thing you can do though is
+instead of using the normal Rails plugin system you could just make a GemPlugin
+that depends on gem_plugin, mongrel, and *rails* gems.  When you do this it will be loaded
+after Mongrel configures Ruby on Rails.  If you put your code in to the init.rb and
+use the resources and configuration features of GemPlugin then you could package a
+very nice little plugin without having people go through the normal plugin method.
+
+I'm not sure if this has any advantages or disadvantages over the current system, but
+other Mongrel supported frameworks (like Camping and Nitro) can use this same technique
+to load plugins that are specific to how Mongrel works.
+
+
diff --git a/site/src/docs/how_many_mongrels.page b/site/src/docs/how_many_mongrels.page
new file mode 100644
index 0000000..7911293
--- /dev/null
+++ b/site/src/docs/how_many_mongrels.page
@@ -0,0 +1,90 @@
+---
+title: Tuning
+inMenu: true
+directoryName: Tuning
+---
+
+h1.  How Many Mongrel Instances Should I Run?
+
+There is no set number that is "best" since that depends on factors like the
+type of application, server hardware, how dynamic the appication is, etc.
+
+I've found that 8-12 mongrel processes per CPU is about right, but I determined
+this by starting with 1 and then doing the following:
+
+h2. Baseline Your Server
+
+Pick a URL to a small file that is running on your apache server and is not
+served by Mongrel at all.  This URL will be your "best possible baseline".
+
+Build your baseline measurement first.  Using httperf, measure the speed of
+your URL so that you know how fast you could possibly get if you served
+everything static in ideal situations.
+
+**Make sure you do this on a different machine over an ideal network.**
+Not your damn wifi over a phone line through sixteen poorly configured routers.
+Right next to the box your testing with a fast switch and only one hop is the
+best test situation.  This removes network latency from your test as a
+confounding factor.
+
+
+h2. Baseline Rails and Mongrel
+
+Pick a page that's a good representative page for your application.  Make sure
+you disable logins to make this test easier to run.  Hit this Rails page and
+compare it to your baseline page.
+
+* If your rails measurement is *faster* than your baseline
+  measurement then you screwed up.  Rails shouldn't be faster than a file
+  off your static server.  Check your config.
+* If your rails measurement is *horribly slow* compared to baseline
+  then you've got some config to do before you even start tuning the
+  number of process.  Repeat this test until one mongrel is as fast as
+  possible.
+
+h2. Tweak
+
+Once you've got a Rails page going at a reasonable speed, then you'll want to
+increase the --rate setting to make sure that it can handle the reported rate.
+
+Finally, alternate between adding a mongrel process and running the test with
+the next highest rate you'd get.  Stop when adding one more server doesn't
+improve your rate.
+
+*Make sure you run one round of the test to get the server "warmed up", and
+then run the real one.*  Heck, run like 5 or 6 just to make sure you're not
+getting a possibly bad reading.
+
+h2. Example
+
+# Run the test and find out that one mongrel can support a @--rate@ of 120 req/second.
+# Add another mongrel and run the test again with @--rate@ 240.  It handles this
+  just find so you add another and get @--rate@ 360.
+# Try another one and it dies.  Giving @--rate@ 480 gets you only a rate of 100.
+  Your server has hit it's max and broke.  
+# Try tuning the @--rate@ down at this and see if it's totally busted (like, 4 mongrels
+  only gets you @--rate@ 380) or if it's pretty close to 480.
+# That should do it.  A good practice is to also look at the CPUs on the
+  server with top and see what kind of thrashing you give the server.
+
+
+h2. HTTPERF
+
+Here's the commands I use for each test, but read the man page for
+httperf so that you learn to use it.  It's an important tool and just
+cut-pasting what I have here is not going to do it for you.
+
+* @httperf --server www.theserver.com --port 80 --uri /tested --num-conns <10 second count>@
+
+* @httperf --server www.theserver.com --port 80 --uri /tested --num-conns <10 second count> --rate <reported req/sec>@
+
+Where @<10 second count>@ is enough connections to make the test run for 10
+seconds.  Start off with like 100 and keep raising it until it goes for 10
+seconds.
+
+Where @<reported req/sec>@ is whatever httperf said the estimated
+requests/second were.  What you're doing here is seeing if it really can handle
+that much concurrency.  Try raising it up and dropping it down to see the
+impact of performance on higher loads.
+
+Have fun.
diff --git a/site/src/docs/howto.page b/site/src/docs/howto.page
new file mode 100644
index 0000000..f59bcfa
--- /dev/null
+++ b/site/src/docs/howto.page
@@ -0,0 +1,490 @@
+---
+title: HOWTO
+inMenu: true
+directoryName: Documentation
+---
+
+h1.  Mongrel HOWTO
+
+After you have "Mongrel running":started.html you can start
+to configure Mongrel and tune it to your specific configuration.
+The "documentation":/docs/index.html page has documentation
+on the various web servers you can run, but this document
+will give you tips and tricks on getting Mongrel running.
+
+
+h2.  Every Start Option Explained
+
+Mongrel is a self-documenting program by giving you an extensive help
+listing for each command.  Simply running *mongrel_rails start -h*
+will print out each possible option and what it does.  Most of
+the options are similar to what you've been using already with
+script/server.
+
+These options are also used in the -C config file option to
+set them without using the command line.  The name used in the
+config file is slightly different since it's a YAML file.  The
+name to use is in parenthesis after the option name.  The
+option names are different from the command line option names
+mostly for historical reasons.
+
+
+<dl>
+<dt>-e, --environment (:environment)</dt>
+<dd>
+Configures your Rails environment to what you need.
+<ul><li><b>Default:</b> development</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-d, --daemonize (:daemon)</dt>
+<dd>
+If given (no options) then Mongrel will run in the background.
+<b>No Win32.</b>
+<ul><li><b>Default:</b> false</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-p, --port (:port)</dt>
+<dd>
+Port to bind to when listening for connections.
+<ul><li><b>Default:</b> 3000</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-a, --address (:host)</dt>
+<dd>
+Address to bind to when listening for connections.
+<ul><li><b>Default:</b> 0.0.0.0 (every interface)</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-l, --log (:log_file)</dt>
+<dd>
+Where to dump log messages in daemon mode.  Use an *absolute* path.
+<b>No Win32.</b>
+<ul><li><b>Default:</b> $PWD/log/mongrel.log</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-P, --pid (:pid_file)</dt>
+<dd>
+Where to write the PID file so <b>start</b> and
+<b>stop</b> commands know the Process ID.  Use *absolute* paths.
+<b>No Win32.</b>
+<ul><li><b>Default:</b> $PWD/log/mongrel.pid</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-n, --num-procs (:num_processors)</dt>
+<dd>
+Maximum number of concurrent processing threads before
+Mongrel starts denying connections and trying to kill
+old threads.
+<ul><li><b>Default:</b> 1024</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-t, --timeout (:timeout)</dt>
+<dd>
+Time to pause (in hundredths of a second) between accepting
+clients. Used as a throttle mechanism.
+<ul><li><b>Default:</b> 0</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-m, --mime, (:mime_map)</dt>
+<dd>
+A YAML file that maps from file extensions to MIME types
+for static files.  It's important that if you are using
+page caching or you have a different language setting--like
+UTF8--then you have to configure this.  Read more below.
+<ul><li><b>Default:</b> not set.</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-c, --chdir (:cwd)</dt>
+<dd>
+Directory to change to prior to starting Mongrel.  "cwd" means
+"change working directory".
+<ul><li><b>Default:</b> . (current directory)</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-r, --root (:docroot)</dt>
+<dd>
+Document root where Mongrel should serve files from.
+If you are putting Mongrel under a different base URI, and
+you want it to serve files out of a different directory then
+you need to set this.
+<ul><li><b>Default:</b> public</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-B, --debug (:debug)</dt>
+<dd>
+Turns on a debugging mode which traces objects, threads, files
+request parameters, and logs accesses writing them to log/mongrel_debug.
+This option makes Mongrel <b>very</b> slow.
+<ul><li><b>Default:</b> false</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-C, --config (NONE)</dt>
+<dd>
+Specifies a configuration YAML file that sets options you're
+reading about right now.  Read "Command Line Settings" below
+for more information.  Use *absolute* paths.
+<ul><li><b>Default:</b> no default</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>-S, --script (:config_script)</dt>
+<dd>
+A special Ruby file that is run after Rails is configured
+to give you the ability to change the configuration with
+Ruby.  This would be where you can load customer Mongrel
+handlers, extra libraries, or setup additional Ruby code.
+This option is fairly advanced so use with caution.
+<ul><li><b>Default:</b> not set</li></ul>
+</dd>
+</dl>
+
+
+<dl>
+<dt>-G, --generate (NONE)</dt>
+<dd>
+Takes whatever options you've set for Mongrel, and the
+current defaults, and then writes them to a YAML file
+suitable for use with the -C option.
+<ul><li><b>Default:</b> not set</li></ul>
+</dd>
+</dl>
+
+<dl>
+<dt>--prefix uri</dt>
+<dd>
+A URI to mount your Rails application at rather than the default
+/.  This URI is stripped off all requests by Rails (not Mongrel)
+so it <b>cannot</b> end in /.
+<ul><li><b>Default:</b> not set</li></ul>
+</dd>
+</dl>
+
+
+<dl>
+<dt>--user USER</dt>
+<dd>
+<b>Must have --group too.</b>
+The user to change to right after creating the listening socket.
+Use this if you have to bind Mongrel to a low port like port 80,
+but don't want Mongrel to run as root.  <b>Not useful in Windows.</b>
+<ul><li><b>Default:</b> not set</li></ul>
+</dd>
+</dl>
+
+
+<dl>
+<dt>--group GROUP</dt>
+<dd>
+<b>Must have --user too.</b>
+The group to change to right after creating the listening socket.
+<b>Not userful in Windows.</b>
+<ul><li><b>Default:</b> not set</li></ul>
+</dd>
+</dl>
+
+h2.  Configuration Files
+
+When Mongrel runs with just *mongrel_rails start* it has
+reasonable defaults for most people's development work with Rails.
+It tries to be as similar to the existing @script/server@ command as
+possible.
+
+When you need to run Mongrel in production (or if you're doing
+wicked fancy stuff) then you'll need to start using a few
+configuration files.  Problem is the configuration file is in
+this weird YAML syntax that most people just hate.  Rather than
+describe the file's syntax and all possible options, Mongrel has
+a -G (generate) feature that will take any command line options
+you give it, generate the YAML file to replicate those options, and
+then exit.  For example, you could make a config file like this:
+
+  @mongrel_rails start -G mongrel_8080.yml -e production -p 8080@
+
+And it'll write all the options possible to mongrel_8080.yml, but
+with your specific changed for environment (-e production) and
+port (-p 8080).
+
+When you run a configuration file with -C, don't pass other options.
+Rather than have complex rules about whether a configuration file or
+command line option wins, mongrel_rails just uses configuration file
+and defaults, or command line options and defaults.   Basically don't mix,
+it won't work.
+
+
+h2. MIME Types
+
+Mongrel comes with a very small set of default MIME types.
+The main theme with Mongrel is that it doesn't interfere with
+the frameworks it hosts.  Many frameworks do their own
+MIME parsing and control, so Mongrel only has just enough to
+serve up a few static files.
+
+The default types are defined in DirHandler as a constant
+and are:
+
+ <pre><code>
+ MIME_TYPES = {
+ ".css"        =>  "text/css",
+ ".gif"        =>  "image/gif",
+ ".htm"        =>  "text/html",
+ ".html"       =>  "text/html",
+ ".jpeg"       =>  "image/jpeg",
+ ".jpg"        =>  "image/jpeg",
+ ".js"         =>  "text/javascript",
+ ".png"        =>  "image/png",
+ ".swf"        =>  "application/x-shockwave-flash",
+ ".txt"        =>  "text/plain"
+ }
+ </code></pre>
+
+Notice that it's just a hash mapping from extension (*with period*)
+to the type that needs to be set.
+
+To change this you just need to write a YAML file that sets
+up your new types or changes these:
+
+ <pre>
+ <code>
+ ---
+ .rss: text/xml
+ </code>
+ </pre>
+
+This would add .rss with the @text/xml@ MIME type.
+
+One problem that comes up quite frequently is that Mongrel's
+DirHandler isn't quite smart enough to know that a page cached
+/feed/rss.html should really be an RSS file with text/xml.
+Mongrel really doesn't have much information to go on, but it
+will happily serve this file up as @text/html@.  The best
+solution to this is to just not use Mongrel's DirHandler, but
+instead use a real web server.  Another option is to write a
+special handler for that URI which knows about it.
+
+You might also need to edit this file if, for example, you use a different encoding such as UTF8.
+You'll want to change all of these MIME types to have the
+proper ending.  For example,if you wanted @charset=EUC-JP@ for
+all your returned static documents, then you'd do:
+
+ <pre>
+ <code>
+ ---
+ .js: text/javascript; charset=EUC-JP
+ .htm: text/html; charset=EUC-JP
+ .html: text/html; charset=EUC-JP
+ .css: text/css; charset=EUC-JP
+ .txt: text/plain; charset=EUC-JP
+ </code>
+ </pre>
+
+You'd also probably need to do this with your Rails pages.
+
+*NOTE:* I'm looking for a method to fix this with a setting or detection.
+
+
+h2. Command Line Settings
+
+Sometimes it's a real pain to set all the command line options
+you need to run Mongrel in production.  Instead of setting the
+options on the command line, you can have Mongrel generate a
+configuration file for you with -G and then pass this (modified)
+file to the -C option next time you start.
+
+For example, if you do this:
+
+ mongrel_rails start -G config/mongrel_opts.conf
+
+Then the mongrel_options.conf will have:
+
+ <pre>
+ <code>
+ ---
+ :config_script:
+ :environment: development
+ :pid_file: log/mongrel.pid
+ :num_processors: 1024
+ :docroot: public
+ :timeout: 0
+ :host: 0.0.0.0
+ :mime_map:
+ :port: 3000
+ :daemon: false
+ :cwd: /home/zedshaw/projects/mongrel/testapp
+ :includes:
+ - mongrel
+ :debug: false
+ :log_file: log/mongrel.log
+ </code>
+ </pre>
+
+The @:blah:@ (two colons) syntax is just how YAML does things.
+You can then either just edit this file and use it with:
+
+ mongrel_rails start -C config/mongrel_opts.conf
+
+Or, you can run the start command again with -G and all the
+options you need to set and it will properly generate the
+config file again.
+
+
+h2. Mongrel Configure Scripts
+
+Mongrel uses a small DSL (Domain Specific Language) to configure
+it's internal workings.  It also lets *you* use this DSL and
+regular Ruby to alter it's internal workings.  The options that
+turn it on are -S or @:config_script:@ in the config file.
+
+Doing this is fairly advanced, but here's how I would create a
+second DirHandler that sits in another directory.  First, create
+a config/mongrel.conf file with this in it:
+
+  @uri "/newstuff", :handler => DirHandler.new("/var/www/newstuff")@
+
+And then do this:
+
+  mongrel_rails start -S config/mongrel.conf
+
+Now when people go to /newstuff they get the files listed there.
+
+This is actually a Ruby file, so you can run
+most Ruby code you need, require libraries, etc.
+
+Main usage for this is to create handlers which run inside Mongrel
+and do extra work.
+
+For more information, read the "RDoc":/rdoc/ for
+"Mongrel::Configurator":/rdoc/classes/Mongrel/Configurator.html
+on what functions are available.
+
+
+h2.  POSIX Signals Used
+
+When you run Mongrel on a POSIX compliant system (meaning *not* Win32)
+you are able to control with signals similar WEBrick or FastCGI.
+
+The signals Mongrel running Rails understands are:
+
+* *TERM* -- Stops mongrel and deleted PID file.
+* *USR2* -- Restarts mongrel (new process) and deletes PID file.
+* *INT* -- Same as USR2, just convenient since CTRL-C is used in debug mode.
+* *HUP* -- Internal reload that might not work so well.
+
+You can use the -S configure script to add your own handlers
+with code like this:
+
+ <pre><code>
+ trap("USR1") { log "I'm doing stuff." }
+ </code></pre>
+
+
+h2.  Super Debugging With Rails
+
+When you use the -B option Mongrel produces *tons* of
+useful debugging output.  The debugging output is actually
+implemented as a small set of handlers in lib/mongrel/debug.rb
+if you're interested in writing your own.
+
+The files that get generated are:
+
+* *rails.log* -- Logs all request parameters exactly as they come to Rails from Mongrel.
+* *objects.log* -- Logs a top 20 count of object types before and after each request.
+* *files.log* -- Logs open files before and after each request.
+* *threads.log* -- Logs active threads before and after each request.
+
+You use these log files to track down weird Rails behavior in your
+application.  Classic example is if your Rails server stops answering
+requests after a certain amount of time.  #1, #2, and #3 cause of this is
+that you are opening files and not closing them.  Turning on -B and
+look in the @files.log@ file will show you exactly what files are
+being leaked.
+
+Another place this helps is if you see that your application is generating
+a lot of RAM.  Look in @objects.log@ and you'll see right away what is the worst
+offending Object.
+
+Finally, the @threads.log@ will tell you if you're leaking threads.
+This happens mostly with people who use IO.popen and don't properly
+clean up the results.  IO.popen in Ruby threads is very tricky,
+and you're better off putting this work into a DRb server anyway.
+
+
+h2.  Installing GemPlugins: mongrel_cluster
+
+Mongrel is extensible via a system called GemPlugins.  They
+are basically autoloaded RubyGems which you install and are
+configured based on how they depend on Mongrel.
+
+A good example is the @mongrel_cluster@ GemPlugin written
+by Bradley Taylor from RailsMachine.  It gives you a nice
+management system for a cluster of Mongrel servers.  This
+is very handy when you are running a large scale deployment
+and I recommend everyone uses it.
+
+You install it simply with:
+
+ $ gem install mongrel_cluster
+
+Once it's installed you can do @mongrel_rails -h@ and it'll
+show you the new commands:
+
+* cluster::configure -- Configures your cluster.
+* cluster::restart -- Restarts it.
+* cluster::start -- Yep, starts it.
+* cluster::stop -- And, yes, stops it.
+
+You can then pass --help to each one to find out the options
+it gets.  You then use it like so:
+
+
+ $ mongrel_rails cluster::configure -p 8080 -e production -a 127.0.0.1
+ $ mongrel_rails cluster::start
+ $ mongrel_rails cluster::stop
+
+If you don't like mongrel_cluster (shame on you!) then you can
+easily remove it with:
+
+ $ gem uninstall mongrel_cluster
+
+And all the commands go away.
+
+
+h1. More Documentation
+
+This should get you started with intermediate Mongrel usage.
+There quite a few more documents in the "Documentation":/docs/index.html
+section in various states of completion.
+
+If you'd like to write one of these documents, then join the
+"mailing list":http://rubyforge.org/mailman/listinfo/mongrel-users
+and volunteer.
+
+
+h1. Credits
+
+Thanks to "Jamie van Dyke":http://www.fearoffish.com/ and mly on #caboose for correcting some
+grammar mistakes.
diff --git a/site/src/docs/index.page b/site/src/docs/index.page
new file mode 100644
index 0000000..8e2a0ff
--- /dev/null
+++ b/site/src/docs/index.page
@@ -0,0 +1,107 @@
+---
+title: Documentation
+inMenu: true
+directoryName: Documentation
+---
+
+h1. Available Documentation
+
+We've got a small set of documentation to get people going.  Most of it is
+geared toward Ruby on Rails but other projects using Mongrel should have their
+own docs that you can refer to based on these.
+
+h2. Contributing Documentation
+
+As you can see many of the pages here are empty.  This is because they are
+being written mostly by one person (Zed) but some folks are now contributing
+documentation so things will go faster.  If you'd like to contribute some
+documentation then read the "instructions on how to do it":contrib.html and
+contact the "mailing list":http://rubyforge.org/mailman/listinfo/mongrel-users
+to announce that you'd like to work on something.
+
+h2. Getting Started
+
+Start here to get a good grounding in getting Mongrel up and running.  These
+documents are targeted at developers who will be starting off using Mongrel and
+might want to throw in a few little tricks.  Serious deployments should check
+out *Deployment Best Practices*.
+
+* "Getting Started":started.html -- Installing and Other things
+* "Win32 HOWTO":win32.html -- Specific instructions for running on windows.
+* "HOWTO":howto.html -- Doing advanced stuff with Mongrel.
+* "Using mongrel_cluster":mongrel_cluster.html -- Nifty plugin for managing your clusters.
+* "Choosing A Deployment":choosing_deployment.html -- How to pick a best practice.
+* "Security":security.html -- Security issues to look at (for any web application).
+* "Frameworks":frameworks.html -- Specific problems and things to know when you run different frameworks.
+
+h2. Deployment Best Practices
+
+These documents are continually changing as deploying Mongrel becomes more
+solid and certain options and configurations start to work the best.  Each one
+is a *best practice* which means that if you do something different then you'll
+have to do your own research.  Best way to work it is to do the *best practice*
+exactly as described, then try to do something weird from there.
+
+* "Apache":apache.html -- The current preferred way to host Mongrel.
+* "Litespeed":litespeed.html -- Another good option, but not open source.
+* "Lighttpd":lighttpd.html -- Using mod_proxy to do a cluster.
+* "Pound":pound.html -- Small scale and dead simple with SSL.
+* "Pen or Balance":pen_balance.html -- Smaller scale without SSL.
+
+
+h2. Advanced
+
+You are a grand master and have answered a few questions on the Mongrel mailing
+list so now it's time to get fancy.
+
+* "Writing Mongrel Plugins":gem_plugin.html -- Writing a GemPlugin for Mongrel.
+* "Distributed Worker":distributed_worker.html -- A common pattern for actions that take forever and block Rails.
+* "Upload Progress Without Rails":upload_progress.html -- Uploading without blocking Rails and giving the user progress.
+
+
+h2. Ruby API Documentation
+
+People writing plugins will want these.
+
+* "Mongrel RDoc":/rdoc/index.html
+* "GemPlugin RDoc":/gem_plugin_rdoc/index.html
+
+
+If there's documentation you'd like then feel free to E-mail the list or post
+to the tracker.
+
+h1. Other People's Documentation
+
+Many other folks have written documentation that they post to their blogs for
+people to use.  I've based a lot of the documentation here on their writings,
+so you should go check out their blogs and shoot them a thanks when you
+can.
+
+* "What About Apache to Mongrel for Rails Applications":http://weblog.textdrive.com/article/219/what-about-apache-to-mongrel-for-rails-applications
+* "Apache 2.2 worker on solaris to a remote mongrel":http://weblog.textdrive.com/article/223/apache-22-worker-on-solaris-to-a-remote-mongrel
+* "Apache 2.2, mod_proxy_balancer and Mongrel":http://weblog.textdrive.com/article/224/apache-22-mod_proxy_balancer-and-mongrel
+* "Scaling Rails with Apache 2.2, mod_proxy_balancer and Mongrel":http://blog.innerewut.de/articles/2006/04/21/scaling-rails-with-apache-2-2-mod_proxy_balancer-and-mongrel
+* "Dead Simple Deployment":http://brainspl.at/articles/2006/04/26/dead-simple-deployment
+* "Deployment Strategies for Rails on Windows servers":http://www.napcs.com/howto/rails/deploy/
+* "mongrel_cluster-0.1.1: the bird dog (capistrano support!)":http://fluxura.com/articles/2006/04/24/easy-mongrel-clustering-with-mongrel_cluster
+* "Easy Mongrel Clustering with mongrel_cluster":http://fluxura.com/articles/2006/05/01/mongrel_cluster-0-1-1-the-bird-dog-capistrano-support
+
+
+h1. Frequently Asked Questions
+
+When people ask questions really frequently the results end up in the
+"FAQ":../faq.html.
+
+
+h1. Mailing Lists
+
+There's a "mailing list":http://rubyforge.org/mailman/listinfo/mongrel-users
+that you should subscribe to if you're looking for help or are interested in
+tracking Mongrel.  We post announcements of pre-release gems you can play with
+to this mailing list and also discuss development of Mongrel there.
+
+Before you start asking for features you should read about
+"bikeshedding":http://www.catb.org/jargon/html/B/bikeshedding.html and
+understand that we're really nice, but sometimes code speaks better than
+rhetoric.
+
diff --git a/site/src/docs/lighttpd.page b/site/src/docs/lighttpd.page
new file mode 100644
index 0000000..973fd2c
--- /dev/null
+++ b/site/src/docs/lighttpd.page
@@ -0,0 +1,278 @@
+---
+title: Lighttpd
+inMenu: true
+directoryName: Documentation
+---
+
+*I'm sad to say that I have to recommend people not use lighttpd anymore.*
+The author hasn't updated the mod_proxy plugin and isn't providing too much
+support for the bugs it has.  If you're running lighttpd and you constantly
+see 500 errors that are never recovered, then you should switch to Apache
+or another web server that can handle properly balancing backends.
+
+
+h1.  Using Lighttpd With Mongrel
+
+It is possible to host an application with just Mongrel since it is
+able to serve files like a normal web server.  Still, no matter
+how fast Mongrel gets it probably can't compete with something
+like lighttpd for serving static files.  Because of this I've
+devised a simple way to setup a lighttpd+Mongrel setup that
+demonstrates clustering four Mongrel servers running the same
+application as backends.
+
+This is very similar to a FastCGI or SCGI setup except that
+you're just using regular HTTP.  Read through the "HOWTO":howto.html
+for information on other possible deployment scenarios.
+
+
+h2.  The Goal
+
+What we want to do is put a lighttpd on the internet and then
+have it proxy back to one of four Mongrel servers.
+
+!SimpleLighttpdMongrelSetup.jpg!
+
+This is actually really trivial and probably doesn't need a diagram
+but I got bored just writing it up.
+
+How it all works is pretty simple:
+
+# Requests come to the lighttpd server.
+# Lighttpd takes each request, and sends it to a backend depending
+  on how you configure it:
+  * hash -- Hashes the request URI and makes sure that it goes to the same backend.
+  * round-robin -- Just chooses another host for each request.
+  * fair -- "Load based, passive balancing."  No idea what that means, but if it's like
+    the rest of lighttpd it probably means it will overload the first one and if that one's
+    busy then it starts using the next ones.
+# Each backend doesn't really care about any of this since it's just a web server.
+
+
+h2. Lighttpd Configuration
+
+For lighttpd you need to have *mod_proxy* in your server.modules setting:
+
+ server.modules = ( "mod_rewrite", "mod_redirect",
+   "mod_access", "mod_accesslog", "mod_compress",
+   "mod_proxy")
+
+Then you need to tell lighttpd where the other backends are located:
+
+ proxy.balance = "fair"
+ proxy.server  = ( "/" =>
+      ( ( "host" => "127.0.0.1", "port" => 8001 ),
+      ( "host" => "127.0.0.1", "port" => 8002 ),
+      ( "host" => "127.0.0.1", "port" => 8003 ),
+      ( "host" => "127.0.0.1", "port" => 8004 ) ) )
+
+When I used lighttpd 1.4.9 and set proxy.balance="round-robin" I had an excessive number of
+500 errors for no real reason.  The "fair" setting seems to be the best, but if you
+have a large number of fairly random URIs you should try "hash" too.
+
+*For the rest of this tutorial we'll assume you're running lighttpd on port 80.*
+
+
+h2. Mongrel Configuration
+
+Mongrel is pretty easy to setup with this configuration on either Win32 or Unix, but
+since lighttpd doesn't compile so easily on Win32 I'll just show the Unix method
+for starting it:
+
+ $ mongrel_rails start -d -p 8001 \
+    -e production -P log/mongrel-1.pid
+ $ mongrel_rails start -d -p 8002 \
+    -e production -P log/mongrel-2.pid
+ $ mongrel_rails start -d -p 8003 \
+    -e production -P log/mongrel-3.pid
+ $ mongrel_rails start -d -p 8004 \
+    -e production -P log/mongrel-4.pid
+
+Now you should be able to hit your web server at port 80 and it'll run against
+one of your four Mongrels.
+
+
+h2.  Testing Stability and Performance
+
+As I mentioned before proxy.balance="round-robin" had many stability issues
+in lighttpd 1.4.9 but how did I figure this out?  Here's how you can do it.
+
+You use "httperf":http://www.hpl.hp.com/research/linux/httperf/ to first hit each
+Mongrel backend with a large request set.  
+
+ $ httperf --port 8001 --server 127.0.0.1 \
+     --num-conns 300 --uri /test
+ $ httperf --port 8002 --server 127.0.0.1 \
+     --num-conns 300 --uri /test
+ $ httperf --port 8003 --server 127.0.0.1 \
+     --num-conns 300 --uri /test
+ $ httperf --port 8004 --server 127.0.0.1 \
+     --num-conns 300 --uri /test
+
+After each of these you're looking for the *Connection rate*, *Request rate*,
+*Reply rate*, and *Reply status*.  You first look at the *Reply status* to make
+sure that you got all 2xx messages.  Then look at the other three and make
+sure they are about the same.
+
+Then you hit lighttpd with a similar request set to confirm that it handles the base case.
+
+ $ httperf --port 80 --server 127.0.0.1 \
+     --num-conns 300 --uri /test
+
+You should get no 5xx errors.  In the case of round-robin there were about 60%
+5xx errors even though the Mongrels were functioning just fine.  The "hash" method
+didn't improve this test's performance since there's only on URI in the test.  It
+seems the "fair" method is the best you can do right now.
+
+Finally you hit lighttpd with a 4x rate to see if it could handle the theoretical limit.
+
+ $ httperf --port 80 --server 127.0.0.1 \
+     --num-conns 10000 --uri /test --rate 600
+
+It will most likely fail miserably and you'll probably see a few 5xx counts in the
+*Reply status* line but that's normal.  What you're looking to do is keep moving
+--rate and --num-conns up/down until you get where the server is just barely
+able to accept the requests without slowing down (i.e. your *Request rate* matches
+your --rate setting).   There will be a point where adding literally one more
+to your --rate setting causes the Request rate to tank. That's your setup's breaking
+point and is the actual requests/second you can handle.
+
+
+h1. Insane Caching Power Magnet
+
+Mongrel (as of 0.3.7) by default supports Rails style page caching
+in the RailsHandler it uses to serve your applications.  What this
+means is that if you do a page cached action (which writes a
+.html file as well as respond) then Mongrel will just serve up
+the cached page instead of bug Rails.
+
+This does give you a large boost in performance, but still not nearly
+as much as if you had lighttpd doing the caching for you.  The optimal
+configuration would be where lighttpd checks for cached pages and then
+served it directly as it already does with FastCGI.
+
+There are some technical problems with this and the lighttpd mod_proxy,
+but thankfully I don't have to go into them because lighttpd now supports
+the "power magnet" and Cache Meta Language (CML).  CML is a small bit
+of the Lua programming language that lets you script lighttpd and tell
+it when to cache or not.  The power magnet feature of CML lets you put
+all requests through one CML script so that you can determine whether
+to cache or not.
+
+h2. Configuration
+
+In order to get everything to work right you'll need a few pieces
+of equipment and make sure they are enabled in your lighttpd build.
+The sample build was done on Debian so that everything would work
+including mod_rewrite, mod_memcache, mod_cml, and mod_redirect.
+
+* lua50, liblua50-dev
+* libpcre3-dev
+* memcached
+* Finally make sure you configure with ./configure --with-lua --with-memcache
+
+Debian people will need to follow these instructions from
+"www.debian-administration.org":http://www.debian-administration.org/articles/20
+for installing from source, and will also need to add these lines to your
+/etc/apt/sources.list:
+
+ deb-src http://http.us.debian.org/debian stable main contrib non-free
+ deb-src http://http.us.debian.org/debian unstable main contrib non-free
+ deb-src http://non-us.debian.org/debian-non-US stable/non-US main contrib non-free
+
+And then do the following:
+
+# Make sure you don't have the source extracted in your current directory.
+# apt-get install devscripts debhelper build-essential fakeroot
+# apt-get update
+# apt-get source lighttpd
+# nano -w lighttpd-1.4.10/debian/rules
+## DEB_CONFIGURE_EXTRA_FLAGS need have at the end:  --with-lua --with-memcache
+# nano -w lighttpd-1.4.10/debian/lighttpd.install
+## debian/tmp/usr/lib/lighttpd/mod_cml.so needs to be added here.
+
+Then you're supposed to be able to follow the debian-administration
+docs but I haven't got it all working yet.  Please clue me in
+if you get this compiled on Debian.
+
+h3. lighttpd.conf
+
+If it all builds right then you'll be able to use this nifty
+CML script that Bradley K. Taylor (from railsmachine.net) came
+up with.  First you need to tweak your lighttpd.conf at the
+place where you have the mod_proxy setup from previous:
+
+ $HTTP["host"] == "www.myhost.come" {
+   server.document-root = "/my/path/to/app/public"
+   cml.power-magnet  = "/my/path/to/app/config/power-magnet.cml"
+   proxy.balance = "fair"
+   proxy.server  = ( "/" => ( ( "host" => "127.0.0.1", "port" => 8001 ),
+                          ( "host" => "127.0.0.1", "port" => 8002 ) ) )
+ }
+
+This one just has two for simplicity.  The big thing is the
+document root setting and the power-magnet.cml setting.  I wouldn't
+put the power-magnet.cml in your public directory.
+
+h3. power-magnet.cml
+
+Now for the magic bit of Lua code that tells lighttpd what to do:
+
+ dr = request["DOCUMENT_ROOT"]
+
+ if file_isreg(dr .. "maintainance.html") then
+   output_include = { dr .. "maintainance.html" }
+   return CACHE_HIT
+ end
+
+ f = request["REQUEST_URI"]
+
+ if f == "/" or f == "" then
+   file = dr .. "index.html"
+ elseif not string.find(f, "%.") then  -- rewrite for cached pages
+   file = dr .. f .. ".html"
+ else
+   file = dr .. f
+ end
+
+ if file_isreg(file) then
+   output_include = { file }
+   return CACHE_HIT
+ end
+
+ return 1     -- should be CACHE_MISS, but there's a bug in 1.4.10
+
+Place this in the /my/path/to/app/config/power-magnet.cml like you
+configured above.
+
+Now if you restart lighttpd and everything worked right you should
+be able to see the headers and tell if Mongrel or lighttpd is serving
+them.  Use curl like this:
+
+ curl -I http://zedapp.railsmachine.net/
+ curl -I http://zedapp.railsmachine.net/admin
+
+The second one should redirect and show a Mongrel header while the
+first one should show a lighttpd header.
+
+
+h2. Memcached
+
+The next installment of this document will tell you how to setup a
+memcached so that you can run the lighttpd on a different server
+from the Mongrel cluster.  Right now they all have to reside
+on one machine.
+
+h2. CML Tricks
+
+Since Lua is a full blown and fast little language
+you can get pretty creative with it.  For example you could
+have it check dates and times of files, look for processes
+that should be running, run commands, check the contents of
+a file, etc.
+
+Take a look at the "Lua Reference Manual":http://www.lua.org/manual/5.0/
+to see what it can do.  Ruby people will probably like Lua.
+
+
+
diff --git a/site/src/docs/litespeed.page b/site/src/docs/litespeed.page
new file mode 100644
index 0000000..bf8c3e2
--- /dev/null
+++ b/site/src/docs/litespeed.page
@@ -0,0 +1,84 @@
+---
+title: LiteSpeed
+inMenu: true
+directoryName: LiteSpeed
+---
+
+h1. LiteSpeed Best Practice Deployment
+
+h3. by "Alison Rowland":http://blog.alisonrowland.com
+
+LiteSpeed makes setting up a reverse proxy to Mongrel a snap with its excellent, web-based control panel. LiteSpeed has a built-in load balancer, so it also works well in conjunction with the "Mongrel_Cluster":mongrel_cluster.html plugin.
+
+h2. Requirements
+
+These instructions assume you have already completed the following steps:
+
+* installed the LiteSpeed Webserver, version 2.1.16 or greater[1] (note: not available for Windows),
+* set up your application as a virtual host[2],
+* installed and configured Mongrel,
+* and confirmed that you can start Mongrel and access your app by appending Mongrel's port number to your domain (e.g. mysite.com:8000).
+
+If you've done all that, then continue reading!
+
+h2. Configuring Mongrel as an External App
+
+# Enter your LiteSpeed Administration Panel (usually yourdomain:7080).
+# Go to *Server Configuration*.
+# Select your app under *Virtual Hosts* in the sidebar at left.
+# Go to the *External Apps* tab and click *Add*.
+# Choose *Web Server* for the *Type* and click *Next*.
+
+Fill in the following fields:
+
+* *Name*: Give this instance of Mongrel a name, such as @myapp-1@.
+* *Address*: This should be @127.0.0.1:XXXX@, where @XXXX@ is the port number your mongrel instance is running on.
+
+The other fields are up to you. Here are some values to start you off with a workable setup:
+
+* *Max Connections*: 20
+* *Connection Keepalive Timeout*: 1000
+* *Environment*: __leave blank__
+* *Initial Request Timeout (secs)*: 1
+* *Retry Timeout (secs)*: 0
+* *Response Buffering*: No
+
+Finally, click *Save*. If you're only running a single instance of Mongrel, skip down to the instructions on *Configuring a Context.* Otherwise, read on.
+
+h2. Load Balancing across Multiple Mongrel Instances
+
+If you're running more than one instance of Mongrel, or are using Mongrel_Cluster, you'll need to repeat the above directions for every instance of Mongrel, changing the name and port number as appropriate for each. Next, you need to set up a load balancer.
+
+# Back on the *External Apps* tab, click *Add*.
+# Choose *Load Balancer* for *Type* and click *Next*.
+# Give it a *Name*, such as @MyApp@
+# In the *Workers* field, enter all of the mongrel instances you set up, using the names you gave them, like so: <br />
+@proxy::myapp-1, proxy::myapp-2, proxy::myapp-3@
+# *Save*.
+
+h2. Configuring a Context
+
+Configuring a context prevents LiteSpeed from displaying Mongrel's port number in the URL.
+
+# Go to your virtual host's *Context* tab, and click *Add*.
+# If you're set up to run on just a single Mongrel instance, select *Proxy*. Otherwise, select *Load Balancer*.
+# Enter @/@ in *URI*.
+# Make sure your *Web Server* or *Load Balancer* is selected in the next field's drop-down menu.
+# The other settings are up to you. Most can be left blank.
+# *Save*.
+
+h2. Finishing Up
+
+The only thing left is to make sure Mongrel is fired up, and, in your LiteSpeed admin panel, click *Apply Changes*, then *Graceful Restart*. You should be good to go!
+
+
+h2. References
+
+Thanks go to Bob Silva[2] and Rick Olson[3], for their trailblazing articles on LiteSpeed deployment for Rails.
+
+fn1. "LiteSpeed Technologies":http://litespeedtech.com
+
+fn2. "Launching Rails at the Speed of Lite with LiteSpeed Webserver":http://www.railtie.net/articles/2006/01/21/up-and-running-in-the-speed-of-light
+
+fn3. "Setting up LiteSpeed with Mongrel":http://weblog.techno-weenie.net/2006/4/11/setting-up-litespeed-with-mongrel
+
diff --git a/site/src/docs/mongrel_cluster.page b/site/src/docs/mongrel_cluster.page
new file mode 100644
index 0000000..4893206
--- /dev/null
+++ b/site/src/docs/mongrel_cluster.page
@@ -0,0 +1,138 @@
+---
+title: mongrel_cluster
+inMenu: true
+directoryName: mongrel_cluster
+---
+
+h1. Using Mongrel Cluster<br>
+<small><small>by Austin Godber</small></small>
+
+"Mongrel_cluster":http://rubyforge.org/projects/railsmachine/ is a
+"GemPlugin":http://mongrel.rubyforge.org/gem_plugin_rdoc that wrappers
+the mongrel HTTP server and simplifies the deployment of webapps
+using a cluster of mongrel servers.  Mongrel_cluster will conveniently configure
+and control several mongrel servers, or groups of mongrel servers, which are
+then load balanced using a reverse proxy solution.  Typical load balancing
+reverse proxies include:
+* "Apache":apache.html - flexible and complex
+* "Lighttpd":lighttpd.html - development has stalled
+* "Pound":pound.html - Simple and SSL capable
+* "Pen/Balance":pen_balance.html - Simple
+
+h2. Requirements
+
+Throughout these instructions we will assume the following:
+* All mongrel instances are running on the same machine
+* Mongrel *0.3.13* or greater
+* "Mongrel_cluster":http://rubyforge.org/projects/railsmachine/ *0.2.0* or greater
+* Linux platform (Centos 4.3 in this case, so you will see RedHat like commands).
+* You have *sudo* or *root* access
+
+h2. Preliminary steps
+
+In general, when deploying a mongrel cluster, none of the mongrel servers will
+be listening on a privileged port.  This is nice, we don't have to run mongrel as
+root, therefore we should create a user for mongrel to run as:
+<pre><code>
+  $ sudo /usr/sbin/adduser -r mongrel
+</code></pre>
+For the purpose of this example we will just use a freshly minted rails app.
+You can adjust these instructions to work with your app, wherever you may have
+placed it but lets pretend we are working in */var/www/apps*.  So lets go set
+up our app and test that mongrel will serve it:
+<pre><code>
+  $ cd /var/www/apps
+  $ rails testapp
+  $ cd testapp
+  $ mongrel_rails start
+</code></pre>
+You should now be able to see your application at @http://host:3000/@.  If you
+can, you are good to go.  Hit @CTRL+C@ to stop the mongrel server.  At a minimum
+the log directory of your app has to be writable by the *mongrel* user:
+<pre><code>
+  $ sudo chown -R mongrel:mongrel /var/www/apps/testapp
+</code></pre>
+
+h2. Mongrel Cluster Setup
+
+With mongrel working and our webapp directory prepared we can proceed with the
+mongrel_cluster configuration step:
+<pre><code>
+  $ sudo mongrel_rails cluster::configure -e production \
+    -p 8000 -N 3 -c /var/www/apps/testapp -a 127.0.0.1 \
+    --user mongrel --group mongrel
+</code></pre>
+This will write a configuration file in *config/mongrel_cluster.yml*.  We have
+setup to run our cluster in production mode as the user *mongrel* and will start
+3 mongrel servers listening on ports 8000, 8001, and 8002.  Now, lets do a quick
+test of what we have setup so far:
+<pre><code>
+   $ sudo mongrel_rails cluster::start
+</code></pre>
+Checking our host on ports 8000, 8001, and 8002 we should now be able to see our
+test application.  We can stop all of those mongrels with
+@sudo mongrel_rails cluster::stop@.
+
+h2. On Boot Initialization Setup
+
+At this point, mongrel and mongrel_cluster are setup and working with our sample
+webapp.  Ultimately, we want this cluster to start on boot.  Fortunately,
+mongrel_cluster comes with an init script that we can just drop into place.  All
+we need to do is put the configuration files in */etc/mongrel_cluster* and take care of
+a few system tasks:
+<pre><code>
+  $ sudo mkdir /etc/mongrel_cluster
+  $ sudo ln -s /var/www/apps/testapp/config/mongrel_cluster.yml \
+    /etc/mongrel_cluster/testapp.yml
+  $ sudo cp \
+    /path/to/mongrel_cluster_gem/resources/mongrel_cluster \
+    /etc/init.d/
+  $ sudo chmod +x /etc/init.d/mongrel_cluster
+</code></pre>
+Now we have a typical System V init script that will launch our mongrel cluster.
+Actually, this script will launch any cluster that has a configuration file in
+*/etc/mongrel_cluster/*.  So when we run */etc/init.d/mongrel_cluster start* it
+will start all clusters.  Likewise for stop and restart.  If we are using a
+RedHat like system we can configure mongrel_cluster for startup:
+<pre><code>
+  $ sudo /sbin/chkconfig --level 345 mongrel_cluster on
+</code></pre>
+For users of Debian, you can use this command to install the script:
+<pre><code>
+  $ sudo /usr/sbin/update-rc.d -f mongrel_cluster defaults
+</code></pre>
+*NOTE* At this point there are a few issues with this init script that only apply
+under certain circumstances.  Those issues include:
+
+* *Shebang line* - The init script uses *#!/usr/bin/env ruby* to find the
+appropriate interpreter.  Some distribution installs of ruby only give you a
+/usr/bin/ruby1.8.  You may change the shebang line or simply create a symbolic
+link from /usr/bin/ruby1.8 to /usr/bin/ruby[3].
+* *mongrel_cluster_ctl location* - If you have installed your gems in
+/usr/local/ you may find that the init script can not find mongrel_cluster_ctl.
+To resolve this, you can symbolically link /usr/local/bin/mongrel_cluster_ctl into
+/usr/bin/
+
+h2.  Conclusion
+
+We have configured mongrel and mongrel_cluster with our webapp and setup
+mongrel_cluster to run our cluster at startup.  What's missing?  Well, unless
+your application users expect to have to connect to ports 8000-8002 you had best
+check out the reverse proxy options listed above.
+
+The process of setting up mongrel_cluster will be the same for all of the
+reverse proxy deployment options.  So this document will likely serve as a reference
+for several of the other deployment guides.
+
+<hr>
+
+fn1.  Thanks to "Bradley Taylor":http://fluxura.com/ for writing
+mongrel_cluster and recent improvements in its startup capabilities.  The
+following people have provided valuable feedback on this document: Alison Rowland.
+
+fn2.  @adduser -r@ is a RedHat-centric way of creating a system account.  For
+Debian-ish distributions replace that with @adduser --system mongrel@.
+
+fn3. If you have this problem, you will probably discover other ruby related
+executables are also missing.  You may want to link irb1.8 and ri1.8 as well,
+though only /usr/bin/ruby is necessary for this init script.
diff --git a/site/src/docs/osx.page b/site/src/docs/osx.page
new file mode 100644
index 0000000..4a4feba
--- /dev/null
+++ b/site/src/docs/osx.page
@@ -0,0 +1,124 @@
+---
+title: OSX
+inMenu: true
+directoryName: OSX
+---
+h1. OS X + Ruby on Rails + Mongrel + MySQL in 15 minutes
+
+*by "Elliott Hird":http://elliotthird.org/*
+
+Most tutorials about this seem to involve either manually compiling everything or they take some totally unneccesary long-winded detour. But it's really easy.
+
+Anyway, let's get started.
+
+h2. Installing MacPorts
+
+_(If you already have MacPorts installed, you can skip this step.)_
+
+You'll be able to follow "this tutorial":http://trac.macosforge.org/projects/macports/wiki/InstallingMacPorts for the most part, but skip installing X11.
+
+_Disclaimer: The time spent installing MacPorts does not add up to the time spent following this tutorial. Yes, I cheated._
+
+h2. Installing Ruby
+
+Well, technically, you already have ruby. Look:
+<pre>
+$ ruby -v
+ruby 1.8.2 [stuff follows]
+</pre>
+
+_(The version number may be different for you.)_
+
+But depending on what OS X version you're on, it's either broken or outdated. Let's get a working copy of 1.8.5. Fire up your "terminal of choice":http://iterm.sourceforge.net/ and install ruby:
+<pre>
+$ sudo port install ruby
+[lots of text showing macports compiling things]
+</pre>
+That was easy, wasn't it?
+
+h2. Installing RubyGems (these titles have very little variation)
+
+Grab the latest RubyGems version from "here":http://rubyforge.org/frs/?group_id=126 (grab either the .tgz or .zip version, either is fine but the .tgz is smaller) and extract it to wherever you want (in Tiger, just double click on it).
+
+Open your terminal of choice and install it:
+<pre>
+$ cd ~/Desktop/rubygems-0.9.0
+$ sudo ruby install.rb
+[things]
+</pre>
+Hopefully that worked. If it didn't, well then, I can't help you. Ask somebody else.
+
+h2. Did that work?
+
+Now simply type:
+<pre>
+$ gem
+[boring usage instructions]
+</pre>
+Yay! RubyGems works (again, if it doesn't, I have no idea what's wrong).
+
+h2. Installing Rails
+
+Now:
+<pre>
+$ sudo gem install rails --include-dependencies
+</pre>
+After a few minutes, it should dump you back to the prompt without errors. Make sure it works:
+<pre>
+$ rails
+</pre>
+If you want to update rails to the latest (at the time of writing) release candidate of 1.2, see the last section. For now, just wait.
+
+h2. MySQL!
+
+You might think MySQL, being a big bloated thing, would take all day to compile. Not so - it only took about 2 minutes for me. Your mileage may vary.
+<pre>
+$ sudo port install mysql +server
+</pre>
+Note the server variant is selected by using +server. This is required, so just leave it, mmkay?
+
+After compiling and installing all that, it should give you a notice about how to start MySQL at startup. I highly reccomend doing this, it doesn't make startup any slower.
+
+If you've told MySQL to start at bootup, reboot now. I'll wait for you.
+
+h2. Add some Mongrel to the mix
+
+This one is simple.
+<pre>
+$ sudo gem install mongrel --include-dependencies
+</pre>
+Choose the first one and wait for it to install.
+
+h2. Testing it out
+
+Alright then.
+<pre>
+$ cd ~/Code
+$ rails test
+$ cd test
+$ mongrel_rails start
+</pre>
+If all goes well Mongrel should start up. To test it, "load this":http://localhost:3000. If you see the Rails welcome screen - you're done!
+
+h2. That's All, Folks!
+
+No, really.
+
+Actually, that was a bit more than 15 minutes, wasn't it? Oh well.
+
+h2. Additional things
+
+These aren't neccesary, but some people like to do them.
+
+h3. Updating Rails to 1.2rc1
+
+This one is easy.
+<pre>
+$ gem update rails --source http://gems.rubyonrails.org/
+--include-depdendencies
+</pre>
+
+h3. Securing MySQL
+
+By default, nobody except localhost can access MySQL, but it allows any user to login (although they can't do anything) and root has no password. I don't see this as a problem since nobody that isn't at your computer can take advantage of this and it's development anyway, but if you want to secure it you're on your own.
+
diff --git a/site/src/docs/pen_balance.page b/site/src/docs/pen_balance.page
new file mode 100644
index 0000000..1799c0f
--- /dev/null
+++ b/site/src/docs/pen_balance.page
@@ -0,0 +1,57 @@
+---
+title: Pen/Balance
+inMenu: true
+directoryName: Pen/Balance
+---
+
+h1. Pen/Balance Best Practice Deployment
+
+Using "Pen":http://siag.nu/pen/ or "Balance":http://www.inlab.de/balance.html to serve
+a cluster of Mongrel servers is a simple way to get good concurrency without
+going wild on your deployment complexity.  What these two programs do is listen on one
+port and then proxy the requests to one of the Mongrel servers in your cluster.
+
+h2. Requirements
+
+First up, you should learn to use "mongrel_cluster":/docs/mongrel_cluster.html to manage
+a cluster of Mongrel servers.  It's a simple GemPlugin that simplifies things and also
+works better with Capistrano.
+
+Second, you need to install wither Pen or Balance.  Either use your package management
+system or install from source.
+
+Finally, you probably can't do this on win32 unless you use Cygwin.
+
+h2. Pen
+
+Once you get Pen installed you just use it like this:
+
+# Make sure that you can run your application like normal and then
+setup "mongrel_cluster":/docs/mongrel_cluster.html so that all of the running Mongrels work.
+# Run this command: pen -H 4000 localhost:3000 localhost:3001
+# Check port 4000 to make sure that Pen is proxying correctly.
+
+As with the Balance instructions below you'll want to create a start-up script so that
+Pen gets started on machine reboots.  The -H adds a "X-Forwarded-For" header to the
+request, which helps if you need to track the client's IP address.  There's plenty
+of other options for pen as well.
+
+NOTE: Pen has experimental support for SSL.  Try it out if you need SSL.
+
+h2. Balance
+
+Balance is pretty simple:
+
+# Make sure that you can run your application like normal and then
+setup "mongrel_cluster":/docs/mongrel_cluster.html so that all of the running Mongrels work.
+# Run this command:  balance 4000 localhost:3001 localhost:3002 ...
+# Hit port 4000 with a browser to see if it's working.
+
+That's all there is to it.  You might want to write a little start-up script that
+starts balance on machine reboots.  Balance has many other options available if
+you need to do more complex stuff, but this is usually all people need.
+
+h2. Limitations
+
+We found that Balance has an upper limit of 15 backend servers.  I haven't heard much
+about Pen, but it's experimental SSL support is interesting.
diff --git a/site/src/docs/pound.page b/site/src/docs/pound.page
new file mode 100644
index 0000000..a4e166b
--- /dev/null
+++ b/site/src/docs/pound.page
@@ -0,0 +1,148 @@
+---
+title: Pound
+inMenu: true
+directoryName: Pound
+---
+
+h1. Pound Best Practice Deployment<br>
+<small><small>By Austin Godber</small></small>
+
+"Pound":http://www.apsis.ch/pound/ is a load-balancing reverse HTTP proxy.  It
+can also handle SSL connections.  Pound, itself, does not serve content but
+just acts as a front end to servers that do.  In this case pound will sit in
+front of a cluster of mongrel servers.  This arrangement is similar to that
+illustrated on the "Using Lighttpd with Mongrel":lighttpd.html page, except
+pound replaces lighttpd.
+
+h2. Requirements
+
+We assume that the following:
+
+* Pound and the mongrel cluster are running on the same machine[1].
+* *Pound 2.0.4* is built and installed, including SSL support if desired.
+* The *mongrel* gem is installed.
+* The *mongrel_cluster* gem is installed.
+
+These instructions were performed on CentOS 4.3 using Ruby 1.8.4 from the
+CentOS 4 test repository.  They should apply on other Linux distributions.
+They may work for other OSes, but please see the "pound
+website":http://www.apsis.ch/pound/ for additional information.
+
+h2. Mongrel Cluster Setup
+
+First we need to prepare our rails application to run in a mongrel cluster.  In
+this example we will use mongrel_cluster to run three mongrel instances on
+ports 8000, 8001, and 8002.  We then launch the mongrel cluster:
+
+ $ cd railsapp/
+ $ mongrel_rails cluster::configure -p 8000 -N 3
+ $ mongrel_rails cluster::start
+
+We should now have three instances of our rails app running on ports 8000,
+8001, and 8002.
+
+h2. Configuring Pound
+
+Now we configure pound to proxy requests to the rails cluster we just created.
+We will configure pound to accept both HTTP and HTTPS traffic on ports 80 and
+443 respectively.  Pound will then proxy requests to the *Service*s listed in
+the configuration file.  Our configuration file (/usr/local/etc/pound.cfg)
+looks like this:
+
+<pre>
+<code>
+ListenHTTP
+  Address 0.0.0.0
+  Port    80
+  Service
+    BackEnd
+      Address 127.0.0.1
+      Port    8000
+    End
+    BackEnd
+      Address 127.0.0.1
+      Port    8001
+    End
+    BackEnd
+      Address 127.0.0.1
+      Port    8002
+    End
+  End
+End
+
+ListenHTTPS
+  Address 0.0.0.0
+  Port    443
+  Cert    "/usr/local/etc/test.pem"
+  # pass along https hint
+  AddHeader "X-Forwarded-Proto: https"
+  HeadRemove "X-Forwarded-Proto"
+  Service
+    BackEnd
+      Address 127.0.0.1
+      Port    8000
+    End
+    BackEnd
+      Address 127.0.0.1
+      Port    8001
+    End
+    BackEnd
+      Address 127.0.0.1
+      Port    8002
+    End
+  End
+End
+</code>
+</pre>
+
+Before starting pound, we need to make sure our SSL certificate is present.  If
+not we can quickly generate a test certificate:
+
+ $ openssl req -x509 -newkey rsa:1024 -keyout test.pem \
+   -out test.pem -days -nodes
+
+It should now be safe to start pound:
+
+ $ sudo pound -f /usr/local/etc/pound.cfg
+
+Our Rails application should now be available at http://127.0.0.1/ and https://127.0.0.1/ .
+
+h2. Testing SSL in Rails
+
+The line @AddHeader "X-Forwarded-Proto: https"@ in the ListenHTTPS section
+tells pound to add a header to the request as it is passed back to the mongrel
+servers[2].  This will tell the rails application that the request was
+originally an SSL request.  We can test this with the following simple Rails
+controller, app/controller/test_controller.rb:
+
+<pre>
+<code>
+class TestController < ApplicationController
+  def index
+    @sslyn = request.ssl?
+  end
+end
+</code>
+</pre>
+
+And the accompanying view, app/views/test/index.rhtml:
+
+<pre>
+<h1>test</h1>
+SSL: < %= @sslyn %>
+</pre>
+
+Visiting @http://127.0.0.1/Test/@ should show @SSL: false@ while visiting
+@https://127.0.0.1/Test/@ should return @SSL: true@.
+
+h2. Building Pound on OSX
+
+OSX has specific problems when building pound, but you can follow "Trotter Cashion's":http://lifecoding.com/blog/?p=29
+to get everything working.
+
+<hr>
+
+fn1. It is not required that pound run on the same machine as the mongrel
+servers.  It was just chosen for this example.
+
+fn2. Thanks to Joshua Harvey's post on the Mongrel mailing list for this fix.
diff --git a/site/src/docs/security.page b/site/src/docs/security.page
new file mode 100644
index 0000000..2781b12
--- /dev/null
+++ b/site/src/docs/security.page
@@ -0,0 +1,94 @@
+---
+title: Security
+inMenu: true
+directoryName: Security
+---
+
+h1. Web Application Security Issues
+
+Mongrel takes a different approach to security than most web servers.  Rather than
+relying on massive human efforts to audit all possible code, Mongrel is implemented
+using algorithms and methods that are difficult to subvert.  There is still auditing
+and checks, but Mongrel simply tries to avoid errors by not doing things that cause them.
+
+Read the "Iron Mongrel Security page":/security.html for information on how security
+is done in Mongrel.  The main points to remember with Mongrel's security are:
+
+* Mongrel uses a "Ragel":http://www.cs.queensu.ca/home/thurston/ragel/ generated parser
+instead of a hand coded HTTP handler.  The grammar is very close to the ABNF specification, so
+if you see "BAD CLIENT" errors in your logs, that probably is a bad client.
+* Security tests have found that Mongrel stops most security attacks at the protocol level due to
+it's correctly written parser *and* it's explicit limits on the sizes of everything.
+* The Mongrel reaction to a protocol violation is to close the socket immediately.  It doesn't waste
+time and resources on bad clients since this is *always* a hack attempt.  If it isn't then it's a
+poorly written client and the author should learn to write a correct one.
+* Mongrel works with all the main clients out there, and ones it doesn't work with are crap living
+in a tiny tiny niche of the internet designed by horrible programmers.
+* While Mongrel is more strict than other servers, it isn't draconian.  The clients that can't get
+through are typically skating on the edge of the HTTP grammar where they do not belong.
+
+Mongrel isn't infallible, but if Mongrel complains about something then you should investigate it.
+If you think Mongrel is wrong then shoot a message to the mailing list detailing what it should do
+and we'll consider adjusting the grammar.  If you think Mongrel should violate the grammar so that
+your little WebDAV++ Social Network Bookmark Chat Web 2.0 monstrosity can see the light of day, then
+you "should write your own web server":/not_mongrel.html instead.
+
+h2. Learning About Web Application Security
+
+You should read the "OWASP":http://www.owasp.org/index.php/Main_Page document
+"Top Ten Project":http://www.owasp.org/index.php/OWASP_Top_Ten_Project for information on
+the big security risks and how to avoid them.  The summary of these is:
+
+* Unvalidated Input
+* Broken Access Control
+* Broken Authentication And Session Management
+* Cross Site Scripting
+* Buffer Overflow
+* Injection Flaws
+* Improper Error Handling
+* Insecure Storage
+* Application Denial Of Service
+* Insecure Configuration Management
+
+Many of these errors depend on how you write your application and have little to do with Mongrel.
+The two that relate the most to Mongrel are *Buffer Overflows* and *Application Denial of Service*.
+
+
+h2. Buffer Overflows
+
+Mongrel is doing some heavy C buffer thrashing internally, but several controls are in place to make
+sure that things stay safe:
+
+* Pointers are checked with asserts and if statements to test if there's been a buffer overflow.
+* Ragel generates a safe state machine that is accurate to the byte level.
+* There are none of the "unsafe" string handling functions except for where absolutely necessary, and
+that one spot is checked heavily.
+* Input is limited to maximum sizes--which also helps prevent denial of service.
+
+
+h2. Application Denial of Service
+
+Normally this is things like using algorithms in your application that make it easy for
+someone to take down your application with simple queries. A good example is a SQL database
+query that when given the right inputs takes forever.  It only takes a few of these to
+destroy your application's response time.
+
+Mongrel helps with Denial of Service by doing the following things:
+
+* Mongrel strict parser boots clients immediately to save on resources and time.
+* Mongrel boots clients that go over the (generous) size limits for input.
+* When Mongrel gets overloaded it starts denying clients and then finds existing
+requests that are taking to long and kills them.  It is pretty conservative about this, but
+you can use options to tune it more or less severe.
+* Mongrel is already using pure HTTP so there's plenty of tools available to help you.
+* It's designed to be as efficient as possible, but this has limits because of Ruby.
+
+Don't count on Mongrel to suddenly make your Rails application withstand a Russian
+DOS blackmail operation though.  It works hard to prevent DOS potential, but there's only
+so much it can do.
+
+If you're very serious about security then you should check out "mod_security":http://www.modsecurity.org/
+which is an Apache module that has lots of active prevention of such things.  It can stop many web
+scanner attacks, DOS attempts, and other security attempts.  It does slow your server down, but it's
+probably worth it if you have something valuable.
+
diff --git a/site/src/docs/started.page b/site/src/docs/started.page
new file mode 100644
index 0000000..5c6f23c
--- /dev/null
+++ b/site/src/docs/started.page
@@ -0,0 +1,83 @@
+---
+title: Getting Started
+inMenu: true
+directoryName: Documentation
+---
+
+h1.  Getting Started
+
+The easiest way to get started with Mongrel is to install it via RubyGems
+and then run a Ruby on Rails application.  You can do this easily:
+
+ $ sudo gem install mongrel
+ $ cd myrailsapp
+ $ mongrel_rails start -d
+
+Which runs Mongrel in the background.  You can stop it with:
+
+ $ mongrel_rails stop
+
+And you're all set.  There's quite a few options you can set for the
+start command.  Use the *mongrel_rails start -h* to see them all.
+
+
+h2. Win32 Install
+
+Windows has a slight difference since it seems that the win32-service doesn't
+get picked up for some people as a dependency.  You'll need to do this instead:
+
+ $ gem install win32-service (pick the most recent one)
+ $ gem install mongrel (pick the win32 pre-built)
+ $ gem install mongrel_service
+
+Now you're installed.  "Read the Win32 HOWTO for more instructions.":win32.html
+
+
+h2. Updating
+
+You should be able to do an *gem update* and get the latest version of Mongrel
+on any platform you've already installed it on.  The caveat to this is if
+you've been grabbing test releases from any of the authors directly then
+you'll need to *gem uninstall* first to make sure you don't have any buggy
+stuff lying around.
+
+
+h1. Help For Commands
+
+Mongrel uses a fairly comprehensive command/plugin system (documented in the near
+future) that has built-in help thanks to optparse.  Just pass a -h to any
+command and it will dump the help for you:
+
+ $ mongrel_rails start -h
+
+Also every option has reasonable default options, and will complain if you give
+anything invalid.
+
+See the "HOWTO":howto.html for information on each option and what
+it does.
+
+h1. Running In Development
+
+Mongrel turns out to be really nice for development since it serves files
+much faster than WEBrick.  I'm using it for almost all my development Ruby
+on Rails work these days.  What I do is the following:
+
+ $ mongrel_rails start
+
+And then do my work like normal with WEBrick.  You don't get all the logging
+and stuff you get with WEBrick (planned for a future release) but otherwise
+it's nice and snappy.
+
+
+h1. More Information
+
+There's a "mailing list":http://rubyforge.org/mailman/listinfo/mongrel-users that
+you should subscribe to if you're looking for help or are interested in tracking
+Mongrel.  We post announcements of pre-release gems you can play with to this
+mailing list and also discuss development of Mongrel there.
+
+Before you start asking for features you should read about
+"bikeshedding":http://www.catb.org/jargon/html/B/bikeshedding.html and
+understand that we're really nice, but sometimes code speaks better than rhetoric.
+
+Finally there's lots of other "documentation.":index.html
diff --git a/site/src/docs/upload_progress.page b/site/src/docs/upload_progress.page
new file mode 100644
index 0000000..05dcc52
--- /dev/null
+++ b/site/src/docs/upload_progress.page
@@ -0,0 +1,136 @@
+---
+title: Upload Progress
+inMenu: true
+directoryName: Upload Progress
+---
+
+h1. Mongrel Upload Progress Plugin
+
+One of the really nice things about Mongrel is its simplicity.  It's very easy
+for someone to take and extend for their own needs.  The Mongrel Upload
+Progress plugin is an example of how I'm able to extend the Mongrel HTTP
+Request object and provide near-realtime progress updates.
+
+The reason why this is a challenge, is because web servers usually gather the
+HTTP request, send it on to the web framework, and wait on a response.  This is
+fine for most requests, because they're too small to cause an issue.  For large
+file uploads this is a usability nightmare. The user is left wondering what
+whether their upload is going through or not.  
+
+To do this, I've written a Mongrel handler that hooks into some basic Request
+callbacks.  To use it, you need to install the gem, and create a small config
+file for it:
+
+<pre><code>gem install mongrel_upload_progress
+
+# config/mongrel_upload_progress.conf
+uri "/",
+  :handler => plugin("/handlers/upload", :path_info => '/files/upload'),
+  :in_front => true
+
+# start mongrel
+mongrel_rails -d -p 3000 -S config/mongrel_upload_progress.conf
+</code></pre>
+
+That config file tells mongrel to load the Upload handler in front of all other
+handlers.  <code>:path_info</code> is passed to it, telling upload_progress to
+only watch the /files/upload action.  There are two more parameters that I'll
+get into later: <code>:frequency</code> and <code>:drb</code>.  I'm using Rails
+as an example, but this should work with any Ruby framework, such as Camping or
+Nitro.
+
+Now that Mongrel is set up, let's create a "basic upload
+form":/docs/upload_progress_form.rhtml.  If you
+look closely you'll notice a few things:
+
+* A unique <code>:upload_id</code> parameter must be sent to the upload_progress handler.  This is so requests don't get mixed up, and the client page has an ID to query with.
+* The &lt;form> tag is targetted to an iFrame to do the uploading.  Certain browsers (like Safari) won't execute javascript while a request is taken place, so this step is necessary.
+* There is a little "javascript library":/docs/upload_progress_javascript.js being used.  This handles the polling and status bar updates.  
+* Notice the form's action is file/upload, just like the upload_progress handler.
+
+The "Rails controller
+actions":/docs/upload_progress_rails.rb for this are very
+simple.  The upload form itself needs no custom code.  The upload action only
+renders javascript to be executed in the iFrame, to modify the contents of the
+parent page.  The progress action is a basic RJS action that updates the
+current status.  Most of the guts of this are implemented in the javascript
+library.  
+
+Here's what happens when you submit the form:
+
+* The UploadProgress class creates a PeriodicalExecuter and gets ready to poll.
+* The browser initiates the upload.
+* Every 3 seconds, the PeriodicalExecuter calls the RJS #progress action and gets back the current status of the file.  
+* Once finished, the iFrame calls <code>window.parent.UploadProgress.finish()</code>, which  removes the status bar and performs any other finishing actions.
+
+How's this work with a single Mongrel process if "Mongrel synchronizes Rails
+requests":http://david.planetargon.us/articles/2006/08/08/why-you-need-multiple-mongrel-instances-with-rails?
+It's actually very careful about locking, synchronizing only the bare minimum.
+The whole time that Mongrel is receiving the request and updating the progress
+is spent _in_ Mongrel, so it can happily serve other requests.  This is how the
+RJS action is able poll while it's uploading.
+
+This is fine and dandy, but not too many sites run on a single Mongrel.  You'll
+quickly run into problems with multiple mongrels since only one Mongrel process
+knows about the upload.  You'll either have to specify a specific mongrel port
+to communicate with, or set up a dedicated mongrel upload process.  The third
+option, is use DRb.
+
+<pre><code># config/mongrel_upload_progress.conf
+uri "/",
+  :handler => plugin("/handlers/upload",
+    :path_info => '/files/upload',
+    :drb => 'druby://0.0.0.0:2999'),
+  :in_front => true
+
+# lib/upload.rb, the upload drb server
+require 'rubygems'
+require 'drb'
+require 'gem_plugin'
+GemPlugin::Manager.instance.load 'mongrel' => GemPlugin::INCLUDE
+DRb.start_service 'druby://0.0.0.0:2999', Mongrel::UploadProgress.new
+DRb.thread.join</code></pre>
+
+Now in addition to starting mongrel, you'll need to start the DRb service too:
+
+<pre><code>ruby lib/upload.rb</code></pre>
+
+The Rails app should work the same as before, but now it is using a shared DRb
+instance to store the updates.  This gives us one other advantage: a console
+interface to the current uploads.
+
+<pre><code># lib/upload_client.rb, a simple upload drb client
+require 'drb'
+DRb.start_service
+
+def get_status
+  DRbObject.new nil, 'druby://0.0.0.0:2999'
+end
+
+# typical console session
+$ irb -r lib/upload_client.rb
+>> uploads = get_status
+>> uploads.list
+=> []
+# start uploading in the browser
+>> uploads.list
+=> ["1157399821"]
+>> uploads.check "1157399821"
+=> {:size=>863467686, :received=>0}</code></pre>
+
+Using DRb gives you a simple way to monitor the status of current uploads in
+progress.  You could also write a simple web frontend for this too, accessing
+the DRb client with Mongrel::Uploads.
+
+One final note is the use of the <code>:frequency</code> option.  By default,
+    the upload progress is marked every three seconds.  This can be modified
+    through the mongrel config file:
+
+<pre><code>uri "/",
+  :handler => plugin("/handlers/upload",
+    :path_info => '/files/upload',
+    :frequency => 1,
+    :drb => 'druby://0.0.0.0:2999'),
+  :in_front => true</code></pre>
+
+
diff --git a/site/src/docs/upload_progress_form.rhtml b/site/src/docs/upload_progress_form.rhtml
new file mode 100644
index 0000000..8a9b675
--- /dev/null
+++ b/site/src/docs/upload_progress_form.rhtml
@@ -0,0 +1,53 @@
+<html>
+  <head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+    <title>mongrel test</title>
+    <%= javascript_include_tag :defaults %>
+<style type="text/css">
+#progress-bar {
+  width:500px;
+  height:25px;
+  margin:15px;
+  border:solid 1px #000;
+  position:relative;
+}
+
+#progress-bar #status-bar {
+  display:block;
+  height:25px;
+  width:0;
+  background-color:#00f;
+  border-right:solid 1px #000;
+  position:absolute;
+  top:0; left:0;
+}
+
+#progress-bar #status-text {
+  display:block;
+  padding: 0 15px;
+  line-height:25px;
+  position:absolute;
+  top:0; left:0;
+}
+</style>
+  </head>
+  <body>
+
+<p><%= link_to (@upid = Time.now.to_i.to_s), :action => 'status', :upload_id => @upid %></p>
+<%= start_form_tag({:action => 'upload', :upload_id => @upid}, {:multipart => true, :target => 'upload',
+      :onsubmit => "UploadProgress.monitor('#{escape_javascript @upid}')"}) %>
+  <div id="file-fields">
+    <p><%= file_field_tag :data %></p>
+  </div>
+  <p><%= link_to_function 'Add File Field', 'UploadProgress.FileField.add()' %>
+  </p>
+  <p><%= submit_tag :Upload %></p>
+</form>
+
+<div id="results"></div>
+<div id="progress-bar"></div>
+
+<iframe id="upload" name="upload" src="about:blank"></iframe>
+
+  </body>
+</html>
diff --git a/site/src/docs/upload_progress_javascript.js b/site/src/docs/upload_progress_javascript.js
new file mode 100644
index 0000000..6fbc51f
--- /dev/null
+++ b/site/src/docs/upload_progress_javascript.js
@@ -0,0 +1,113 @@
+var UploadProgress = {
+  uploading: null,
+  monitor: function(upid) {
+    if(!this.periodicExecuter) {
+      this.periodicExecuter = new PeriodicalExecuter(function() {
+        if(!UploadProgress.uploading) return;
+        new Ajax.Request('/files/progress?upload_id=' + upid);
+      }, 3);
+    }
+
+    this.uploading = true;
+    this.StatusBar.create();
+  },
+
+  update: function(total, current) {
+    if(!this.uploading) return;
+    var status     = current / total;
+    var statusHTML = status.toPercentage();
+    $('results').innerHTML   = statusHTML + "<br /><small>" + current.toHumanSize() + ' of ' + total.toHumanSize() + " uploaded.</small>";
+    this.StatusBar.update(status, statusHTML);
+  },
+  
+  finish: function() {
+    this.uploading = false;
+    this.StatusBar.finish();
+    $('results').innerHTML = 'finished!';
+  },
+  
+  cancel: function(msg) {
+    if(!this.uploading) return;
+    this.uploading = false;
+    if(this.StatusBar.statusText) this.StatusBar.statusText.innerHTML = msg || 'canceled';
+  },
+  
+  StatusBar: {
+    statusBar: null,
+    statusText: null,
+    statusBarWidth: 500,
+  
+    create: function() {
+      this.statusBar  = this._createStatus('status-bar');
+      this.statusText = this._createStatus('status-text');
+      this.statusText.innerHTML  = '0%';
+      this.statusBar.style.width = '0';
+    },
+
+    update: function(status, statusHTML) {
+      this.statusText.innerHTML = statusHTML;
+      this.statusBar.style.width = Math.floor(this.statusBarWidth * status);
+    },
+
+    finish: function() {
+      this.statusText.innerHTML  = '100%';
+      this.statusBar.style.width = '100%';
+    },
+    
+    _createStatus: function(id) {
+      el = $(id);
+      if(!el) {
+        el = document.createElement('span');
+        el.setAttribute('id', id);
+        $('progress-bar').appendChild(el);
+      }
+      return el;
+    }
+  },
+  
+  FileField: {
+    add: function() {
+      new Insertion.Bottom('file-fields', '<p style="display:none"><input id="data" name="data" type="file" /> <a href="#" onclick="UploadProgress.FileField.remove(this);return false;">x</a></p>')
+      $$('#file-fields p').last().visualEffect('blind_down', {duration:0.3});
+    },
+    
+    remove: function(anchor) {
+      anchor.parentNode.visualEffect('drop_out', {duration:0.25});
+    }
+  }
+}
+
+Number.prototype.bytes     = function() { return this; };
+Number.prototype.kilobytes = function() { return this *  1024; };
+Number.prototype.megabytes = function() { return this * (1024).kilobytes(); };
+Number.prototype.gigabytes = function() { return this * (1024).megabytes(); };
+Number.prototype.terabytes = function() { return this * (1024).gigabytes(); };
+Number.prototype.petabytes = function() { return this * (1024).terabytes(); };
+Number.prototype.exabytes =  function() { return this * (1024).petabytes(); };
+['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte', 'petabyte', 'exabyte'].each(function(meth) {
+  Number.prototype[meth] = Number.prototype[meth+'s'];
+});
+
+Number.prototype.toPrecision = function() {
+  var precision = arguments[0] || 2;
+  var s         = Math.round(this * Math.pow(10, precision)).toString();
+  var pos       = s.length - precision;
+  var last      = s.substr(pos, precision);
+  return s.substr(0, pos) + (last.match("^0{" + precision + "}$") ? '' : '.' + last);
+}
+
+// (1/10).toPercentage()
+// # => '10%'
+Number.prototype.toPercentage = function() {
+  return (this * 100).toPrecision() + '%';
+}
+
+Number.prototype.toHumanSize = function() {
+  if(this < (1).kilobyte())  return this + " Bytes";
+  if(this < (1).megabyte())  return (this / (1).kilobyte()).toPrecision()  + ' KB';
+  if(this < (1).gigabytes()) return (this / (1).megabyte()).toPrecision()  + ' MB';
+  if(this < (1).terabytes()) return (this / (1).gigabytes()).toPrecision() + ' GB';
+  if(this < (1).petabytes()) return (this / (1).terabytes()).toPrecision() + ' TB';
+  if(this < (1).exabytes())  return (this / (1).petabytes()).toPrecision() + ' PB';
+                             return (this / (1).exabytes()).toPrecision()  + ' EB';
+}
diff --git a/site/src/docs/upload_progress_rails.rb b/site/src/docs/upload_progress_rails.rb
new file mode 100644
index 0000000..d04d658
--- /dev/null
+++ b/site/src/docs/upload_progress_rails.rb
@@ -0,0 +1,14 @@
+class FilesController < ApplicationController
+  session :off, :only => :progress
+  
+  def progress
+    render :update do |page|
+      @status = Mongrel::Uploads.check(params[:upload_id])
+      page.upload_progress.update(@status[:size], @status[:received]) if @status
+    end
+  end
+  
+  def upload
+    render :text => %(UPLOADED: #{params.inspect}.<script type="text/javascript">window.parent.UploadProgress.finish();</script>)
+  end
+end
diff --git a/site/src/docs/win32.page b/site/src/docs/win32.page
new file mode 100644
index 0000000..c3e386f
--- /dev/null
+++ b/site/src/docs/win32.page
@@ -0,0 +1,131 @@
+---
+title: Win32 HOWTO
+inMenu: true
+directoryName: Documentation
+---
+
+h1. Mongrel Win32 HOWTO
+
+Mongrel now supports Win32 much better than previous releases thanks to
+some "great people":../attributions.html and their hard work.  You can
+now run Mongrel with Ruby on Rails as a windows service, ang there are
+pre-compiled gems available for people to use.
+
+*Before reading this document you need to read "Getting Started.":started.html and make sure it works.*
+
+h2. Installing Service Support
+
+Mongrel used to have a separate mongrel_rails_service script but this
+caused problems and has since been unified into just mongrel_rails
+and a special GemPlugin that gives you a set of service:: commands.
+
+To install the mongrel_service GemPlugin you simply install mongrel and
+then do:
+
+  > gem install mongrel_service
+
+This will give you a set of service commands that you can find out about
+by just running mongrel_rails and then passing each one the -h option to
+get help.
+
+
+h2. Running The Service
+
+After you do the gem install, find a Rails application you want to run
+and do:
+
+ $ mongrel_rails service::install -N myapp \
+     -c c:\my\path\to\myapp -p 4000 -e production
+ $ mongrel_rails service::start -N myapp
+
+Now hit the port and poof, works (or should).
+
+The application will stop if you use:
+
+ $ mongrel_rails service::stop -N myapp
+
+@NOTE: Stop reports an exception but does stop the service.@
+
+Now the really great thing is that you can just do all this from
+the Services control panel like your Rails application is a regular
+Windows service.
+
+Even works in development mode, which is pretty nice.  I use win32
+at work now and what I have setup is three services:  myapp_dev,
+myapp_stage, myapp_prod.  I point dev and stage at the same
+directory but run dev in *development* mode and stage in *production*
+mode.  Then I have myapp_prod in a separate directory and when I'm
+about to claim I've got something to release I'll go simulate a
+subversion check-out and run my tests again.
+
+
+h2. Other Service Commands
+
+There is a full set of service control commands in the mongrel_service plugin.
+This lets you use either the Services control panel or a command line script to
+manage your Rails applications.  What's also nice is that you can register as many
+applications as you want, and even the same one with different names.
+
+
+h3. service::install
+
+If you want to run the same app in different modes then use the *-N* option to the *install*
+command:
+
+ $ mongrel_rails service::install -N myapp_dev \
+     -c c:\my\path\to\myapp -p 4000 -e development
+ $ mongrel_rails service::start -N myapp
+
+You can also use the *-D* option to give the service a different display name in the
+Services console.
+
+h3. service::start
+
+Pretty much just takes a service name to start up.  It will run and print a message
+until the service finally starts, which sometimes can take 10-60 seconds.
+
+h3. service::stop
+
+Sort of works right now and also only takes a -N parameter.  It has a few errors
+when it tries to stop a service so we're working on making it cleaner.
+
+*NOTE:* since mongrel_service 0.3.1, start and stop commands were removed.
+Use net start / net stop instead.
+
+h3. service::remove
+
+Takes the name (-N) of the service to remove and then removes it from the list.
+*This would be how you'd remove a service so you can change it's start-up options.*
+
+
+h2. CPU Affinity
+
+Mongrel's win32 support actually is able to set the CPU affinity of a running
+Mongrel service.  This is pretty neat since it means if you're running a
+fancy SMP machine or a dual core that pretends to be SMP, then you can
+force Mongrel onto one of them and get a nice little boost.
+
+It's pretty easy to use, just pass the *-u or --cpu* option to the *install*
+command and give a CPU of 1-X.  That means if you have 4 CPUs and you want
+Mongrel on #4 then do:
+
+ $ mongrel_rails service::install -N myapp \
+     -c c:\my\path\to\myapp -p 4000 -e production -u 4
+
+Pretty much the same command, just one more option and you're done.
+
+
+h2. Making you Service autostart with Windows
+
+By default, the new Mongrel service get installed to be run _manually_, using
+Mongrel's commands or the Service Manager. You could tweak it to start automatically
+when Windows start, just use the Service Control commandline tool:
+
+ $ sc config myapp start= auto
+
+Also, you can configure the services that are neede to make it work, like database
+support:
+
+ $ sc config myapp start= auto dependency= MySql
+
+The space after the equal sign is needed for the command to complete successfully.