Apache 1.3, Rails & lighttpd
March 27th, 2007
Apart from the WordPress blog, the dynamic parts of my Reinvented Software site is all Ruby on Rails. The pages there could be better (i.e. sexier), but I ran out of self-imposed time. I spent a few weeks last year rewriting those pages and what used to be an entire J2EE backend in Rails and felt cleansed as a result.
(Yes, I know J2EE was complete overkill – it would be for running the Universe – but when I set up the business, I wanted to keep my hand in just in case things didn’t work out and I’d end up back in corporate hell. Thankfully, that didn’t happen.)
My biggest concern was how to serve the files. My server is running Apache 1.3.x, I could have upgraded to Apache 2.0 but that would been a lot of work. I also heard Apache 2 working with FastCGI could be quite heavy on resources and that was off-putting. I could have moved entirely to lighttpd, but that was too scary, so I decided it would be better to serve the Rails stuff with lighttpd and have Apache do the rest.
I wrote about this on my personal blog at the time (boring my non-geek friends in the process). From the original post:
Apache proxies requests to Lighttpd to serve the Rails stuff (so, for example, you see http://reinventedsoftware.com/store/ instead of http://reinventedsoftware.com:3000/store/), it all works seamlessly.
While I could find instructions out there on how to get Apache proxy to Lighttpd to serve an entire Rails application from a specific URL (e.g. http://reinventedsoftware.com/myrailsapp/) this mixing and matching wasn’t documented – so I will probably put something about this on the Rails Wiki. It was quite straightforward once I had worked it all out.
Zach Hale came across the post and asked how to set up Apache to work alongside lighttpd, so here is how I did it. Note these instructions are for Apache 1.3.x, I don’t know how it would work with Apache 2:
Apache Setup
In Apache’s httpd.conf, ensure mod_proxy is loaded:
LoadModule proxy_module libexec/libproxy.so
Then use the ProxyPass and ProxyPassReverse directives to lighttpd for certain paths (note the standard Rails stylesheets and javascripts directories also):
ProxyPass /news http://localhost:3000/news ProxyPassReverse /news http://localhost:3000/news ProxyPass /support http://localhost:3000/support ProxyPassReverse /support http://localhost:3000/support ProxyPass /stylesheets http://localhost:3000/stylesheets ProxyPassReverse /stylesheets http://localhost:3000/stylesheets ProxyPass /javascripts http://localhost:3000/javascripts ProxyPassReverse /javascripts http://localhost:3000/javascripts
Lighttpd
In lighttpd.conf ensure server.modules includes mod_alias and mod_proxy:
server.modules = ( "mod_rewrite", "mod_accesslog", "mod_fastcgi",
"mod_compress", "mod_expire", "mod_alias", "mod_proxy" )
And further down, add this to handle the aliasing:
$HTTP["url"] =~ "^/" {
server.document-root = CWD + "/public/"
alias.url = ( "/" => CWD + "/public/" )
accesslog.filename = CWD + "/log/access.log"
server.error-handler-404 = "dispatch.fcgi"
server.errorlog = CWD + "/log/lighttpd.error.log"
server.indexfiles = ( "index.html" , "dispatch.fcgi" )
# rails stuff
fastcgi.server = ( ".fcgi" =>
(
(
"socket" => CWD + "/log/code.socket",
"min-procs" => 2,
"max-procs" => 2,
"bin-path" => CWD + "/public/dispatch.fcgi",
"bin-environment" => ( "RAILS_ENV" => "production" )
)))
}
I barely understand this stuff, so don’t ask me to explain it.
Finally, I created symlinks to all the root level folders in the Apache served public_html directory, so that lighttpd could find the files when the user navigates. Here’s a cut down ls -l:
dispatch.rb dispatch.fcgi dispatch.cgi stylesheets javascripts support -> ../../../public_html/support/ news -> ../../../public_html/news feeder -> ../../../public_html/feeder kit -> ../../../public_html/kit about -> ../../../public_html/about blog -> ../../../public_html/blog 404.html 500.html
So, it’s a bit of a hybrid system. Apache is in control and serves most files, but lighttpd takes care of all the Rails stuff. It’s been running for 10 months now through some very heavy moments and works really well.
Leave a Reply