Apache 2.0.x + Mongrel + mod_proxy + mod_rewrite configuration
When I decided to try the switch from fcgid to mod_proxy + mongrel for this blog (and now the majority of my projects at work), I discovered there was no example of such configuration or at least not all in one place.
This post will try to fill this lack of a complete example. The distro i’m using here is Debian, but the configuration should be easily ported to yours.
Thereafter I assume you already have a working configuration with :
- Apache 2.0.x - mod_proxy_http (thanks AMicky) - mod_proxy - mod_rewritemod_proxy configuration :
There’s not so much to change here, just allow proxying to anyone for local domains.
/etc/apache2/mods-available/proxy.conf
<Proxy *>
Order deny,allow
- next line was Deny from all
Allow from all
</Proxy>
A sample vhost file
This configuration is intended to be used with a RubyOnRails application served by Mongrel and deployed with Capistrano.
So you should notice some nice things, like auto-disabling website with a personalized message when there’s a maintenance.html page found, serving static contents directly by apache (no uneeded hit on mongrel) and conserving access to cgi-bin directory (see my previous post about awstats).
/etc/apache2/sites-available/zone.mydomain.tld.conf
<VirtualHost *>
- Set the domain
ServerName mydomain.tld- Set domain aliases
ServerAlias www.mydomain.tld
ServerAlias web.mydomain.tld
- Set the DocumentRoot, this is where apache will look for static files
- This is the public directory of your rails application
- As previously stated, my app is deployed with Capistrano, so I set DocumentRoot to the current/public directory
DocumentRoot /var/www/mydomain.tld/current/public/
- Set where you want apache put its logs
- note I use deflate as log format, this is because I use mod_deflate to compress all outputs
CustomLog /var/www/mydomain.tld/logs/access.log deflate
ErrorLog /var/www/mydomain.tld/logs/error.log
- if you want to have server-wide statistics,
- you can also tell apache to log in a common file shared by all your domains
CustomLog /var/log/apache2/access.log deflate
ErrorLog /var/log/apache2/error.log
- I use utf-8 for all my projects, so I force apache to send the good charset by default.
- This is needed if you use page caching and want apache serves these with the good charset.
AddDefaultCharset utf-8AllowOverride All Order allow,deny Allow from all </Directory>
- Allow limited access to your public directory
- dont allow user to list directories
- allow apache to FollowSymlinks
<Directory /var/www/mydomain.tld/current/public/>
Options -Indexes FollowSymLinks
- Be sure mod_rewrite is activated for you vhost
RewriteEngine On
- If you use applications which resides in cgi-bin, like awstats
- the following mod_rewrite RewriteRule will allow apache to know it should not proxy these request and the PT switch will allow the ScriptAlias directive to work
RewriteRule "^/cgi-bin/." "$0" [QSA,PT,L]
RewriteRule "^/awstatsicon/." "$0" [PT,L]
- Set a ScriptAlias for /cgi-bin/ url
- All url begining with /cgi-bin/ will be served from the specified cgi-bin deirectory
ScriptAlias /cgi-bin/ /var/www/mydomain.tld/cgi-bin/
<Directory /var/www/mydomain.tld/cgi-bin/>
AllowOverride All
Options ExecCGI FollowSymLinks
Order allow,deny
Allow from all
</Directory>
- Do not allow open proxying, allow only requests starting with a /
<LocationMatch "^[^/]">
Deny from all
</LocationMatch>
- Avoid open you server to proxying
ProxyRequests Off
- Let apache correctly rewrite redirect
ProxyPassReverse / http://localhost:8001/
- Let apache pass the original host not the ProxyPass one
ProxyPreserveHost On
- As I mentioned earlier, Capistrano disable_web task allows you to disable your application
- In fact it only create a simple page named maintenance.html in the directory public/system/ of your application
- The following mod_rewrite rules will tell apache to directly serve the maintenance.html pages if it find it out.
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [L]
- For static files it's good to avoid hitting your mongrel process
- so let apache knows it should serve it directly
- for a rails application it means, files in images / stylesheets / javascripts
RewriteRule "^/(images|stylesheets|javascripts)/?(.*)" "$0" [L]- Try to match a cached pages
RewriteRule ([.]+)$ $1.html [QSA]- if the cached page does not exists
RewriteCond %{REQUEST_FILENAME} !-f- proxy requests to your mongrel instance
RewriteRule "^/(.*)" "http://localhost:8001/$1" [P,QSA,L]
</VirtualHost>
Switch to Apache + mod_proxy + Mongrel
In my quest to find the best rails configuration, I decided to try a new alternative to Apache+FastCGI/Apache+FCGID/Lighttpd+FastCGI.
Everyone seems to be focused on Mongrel combined with Apache 2.2 + mod_proxy_balancer. It looks good but Apache 2.2 isn’t actually in Debian (not even in unstable), and as I choose to switch this blog from a Fedora Core 2 (ooch !) server to another server of mine powered by Debian, it really doesn’t fits my needs.
So I choosed to try a different approach and use Apache 2.0.x + mod_proxy + Mongrel. This solution, gives me the possibility to use mongrel_cluster for process management, even if actually I don’t have multiple mongrel instances, and add a load balancer (Pen/Balance/Pound) if needed.
This setup seems to be sufficient for this blog, which runs the latest Typo (3.99.3).
Let me know if you see any differences with the previous configuration.[…]