Most of the Rails projects I work on end up running on either a dedicated server or virtual server where I have root access. This gives me full control over the stack and usually guarantees that I have no issues deploying the applications. But from time to time, I work on smaller projects which have a smaller budget. and the answer of course is shared hosting. Which sucks. Usually.
In the past, I recommended Dreamhost to my clients as they support modern versions of rails and ruby and allow ssh login (which means things like git and installing your own binaries is possible). But the performance of the apps on Dreamhost was borderline – sometimes it was acceptable, and sometimes it wasn’t. And a couple of times, I had to request they move our account to a different server in order to fix that. It got embarrassing after a while to show clients their brand new, shiny site/app on a slow server like this.
Next, I used HostingRails.com, and that did the trick for a few years. The performance was better than Dreamhost, no reliability issues, and clients were happy. They even support Rails 3 now. However last month I was finishing up a Rails 3.1 app (on Ruby 1.9.2) for a client and was hard-pressed to find a shared host that supported that. After several sessions of Googling, I found WebFaction. They had ssh access and supported Rails 3.1 according to their knowledge base. Those were my main criteria, and the rave reviews I kept finding sealed the deal.
The pricing for WebFaction is very simple – $9.50/month for a month-to-month billing plan, and by pre-paying, you can bring it down to as low as $5.50/month (that’s for a 5-year payment). My client signed up and we got an email from WebFaction with all our login and password shortly after.
Upon logging in, I saw their homegrown control panel. It was very simple and easy to navigate – a welcome change from cpanel (blech!). The main concepts I was interested in were “Domains / websites” and “Databases”. Under “Domains / websites”, I saw my client’s domain and websites was already setup (a domain can have multiple web sites inside it, each mapped to a different subdomain). Then there are “Applications”, which get mounted inside a website. You can mount multiple “Site apps” inside your website – a custom Rails app at “/”, AWStats at “/awstats”, a WordPress blog at “/blog”, etc.
The way this works is that WebFaction has preconfigured templates for Django, Drupal, PHP, Redmine, Rails, and WordPress to name a few. And of course you can choose “Custom” to do things that they don’t support out of the box. I chose Rails for the “App Category”, then chose “Rails 3.1 (nginx 1.0.6/Passenger 3.0.9/Ruby Enterprise Edition 1.8.7) as my app was Rails 3.1. You are basically choosing which stack configuration you want your app to run on.
After I clicked “Create”, I logged in via ssh to check out the directory structure. There’s a ”webapps” directory in your home directory containing each of the apps you configure through the control panel (in my case it was called “rails”). Inside webapps/rails was a sample rails app, which I deleted and I then did a git clone of my project to put the app inside webapps/rails.
So far, so good. I setup my database in the control panel, put that info into database.yml, and ran “RAILS_ENV=production bundle exec rake db:setup”. And that’s when the trouble started. If you recall, my app was developed to run on Rails 3.1 and Ruby 1.9.2. The WebFaction stack was using Ruby Enterprise Edition 1.8.7. I’d run into this a few times before, and it came down to changing some of the rails-generated config files to use ruby 1.8.7 hash syntax instead of the new 1.9 syntax. Once I made those changes, we were good to go.
I ran the webapps/rails/bin/restart command to restart my nginx instance, and then the site was working. And it was fast, REALLY fast. WebFaction makes sure your application is running via a cronjob, so there’s no waiting around for Rails to startup if nobody has visited your site in a while. But of course I couldn’t leave well enough alone – I wanted to run ruby 1.9.2 on WebFaction. They’ve since release a new application template for Rails 3.2.1/ruby-1.9.3, but that did not exist at the time I was deploying my app, so I had to install my custom ruby in my account using RVM. Fortunately, it was pretty easy to do. Here’s the steps required:
- Install rvm under my ssh account.
- Install ruby 1.9.2 in rvm
- Create an rvm gemset for my app
- Create an rvm wrapper to run ruby 1.9.2 with that gemset (rvm wrappers are a really useful concept, check the rvm github page for more info.)
- Modify nginx config to use the new wrapper as it’s “passenger_ruby”.
- Install same version of the passenger gem into ruby 1.9.2 as ree 1.8.7 has.
Step 6 was kind of subtle – I was able to install passenger under ruby 1.9.2, but was unable to compile the nginx passenger module. So I reused the one that was already there (by leaving the passenger_root nginx configuration alone) figuring it would work fine. And it did, but I used the same version in case the ruby part of the passenger gem was connected to the nginx module.
Another nginx restart, and it was all running under ruby 1.9.2.
So, to recap: WebFaction is great. They have a simple control panel, intelligent, built-in stack templates, and the ability to customize everything if the templates don’t work for you. WebFaction will be my goto solution when I need shared hosting for as long as they’re in business.