Rails Routing with Phusion Passenger to support multiple apps on a single domain

Late last year, we published a custom Ruby on Rails web application for a college instructor. She wanted to provide her students with a specific learning activity and then monitor if, and how, it improved their mastery of some critical material. The app had two equally important parts: the UI front-end for students and the data collection backend for the instructor.

After the project was completed, our customer began using the app in her own teaching and showing it to colleagues.  Several expressed interest in integrating the app into their own courses. This was good news; the customer had always hoped she might be able to license the app to others and, perhaps, builds up a revenue stream from it.  She was eager to explore the business opportunity but wanted to have a strict separation of the data collected for each instructor, both for simplicity and for privacy considerations.

The ‘right’ way to provide this separation, if the current interest turns into a real opportunity, is for us to develop a more robust administrative back-end for the app, with role-based administration that would let each instructor manage his or her own students and their data.  But, in the spirit of providing a minimum viable product to allow the customer to explore the opportunity without sinking a lot of money into development, we came up with the idea of creating a single site with multiple copies of the application, each with its own database.  We figured that for a reasonably stable codebase, the duplication of installed code would create minimal problems for the first 2, 3, maybe even 5 customers.  After that, she’d have to invest in admin code if she wanted to support more.

And, at first glance, the approach seemed simple enough from a technical perspective. My famous last words.

In reality, this was a complex problem containing several hidden pitfalls, and requiring a high degree of knowledge in both Phusion Passenger and Rails configuration. I was surprised by how little documentation I could find on more advanced topics in the areas of Rails configuration, Rails deployment, and Rails routing. I found my ‘simple approach’ was actually a recipe for a few hard days of research, experimentation, and work.

Continue Reading →