Skip to Main Content
Official App
Free – Google Play
FreshBooks is Loved by American Small Business Owners
FreshBooks is Loved by Canadian Small Business Owners
FreshBooks is Loved by Small Business Owners in the UK
Dev Blog

How To Run a Stealth Rails Application

by justin on April 1/2009

I’ve got a little secret to share about our technology stack here at FreshBooks.  Although by all appearances we are just another PHP shop, FreshBooks has actually been powered by for about three years now.  Here’s how we did it:

Back in late 2005 when Rails hit the mainstream, we were eager to do a complete bottom-up rewrite.  However, management was rather concerned that our customers would react negatively to such a radical technology change.  Would people trust their financial data with an unproven web framework that had only recently been publicly released?  To stay on the safe side, we decided to disguise the new Rails app to appear as though it was still the old PHP version.

Thanks to Rails’ flexibility, this was surprisingly easy to achieve.  The heart of the disguise is a single line added to our routes.rb file:

map.connect ':fake_filename.php', :controller => 'php', :action => 'dispatch'

This takes what appear to be requests for php files and sends them over to our PhpController controller.  In the dispatch action, we lookup the “filename” that was requested and map it to an action and a controller to actually handle the request.

class PhpController < ApplicationController
'about' => { :controller => 'about', :action => 'index' },
'pricing' => { :controller => 'pricing', :action => 'index' },
# ...snip…
def dispatch
redirect_to :controller => FILENAME_ROUTES[params[:fake_filename]][:controller], :action => FILENAME_ROUTES[params[:fake_filename]][:action]

Sure, there is a little performance hit with the redirect, but we’ve found that most users don’t really notice.

We use Apache (with mod_proxy) to send requests to Webrick application servers.  Although it uses a lot of memory, our Webrick cluster has held up surprisingly well.  We’ve been meaning to switch to something more modern like FastCGI + lighttpd so we’ll keep you posted.

Anyway, I hope that this hasn’t come as too much of a shock to anyone. We’ve been running this setup for quite a while and felt it was time to come clean (although some people have suspected that this is what we were up to for some time now).