Explaining Ruby on Rails Infrastructure Alternatives
Last week, I had a workshop on Rails infrastructure, deployment and hosting for one of the major hosting companies in Czech Republic, Active24.
I was confronted with the task of explaining and showing the various pieces (web server, application server, configurations, RubyGems management, etc) without browsing some previously setup server, opening configuration files in Vim, and relying on blind luck that all this will somehow click together for my audience.
So, I’ve decided early on that I need to use some “recipe” definition for showing what are the packages and components and then use those those recipes to install a full Rails stack on a clean machine. You’ll find them all in a Github repository: karmi/rails-deployment-setups-sprinkle.
I quickly rejected Chef or Puppet for this task: I wanted the attendees to be able to provision a clean VPS with a Rails stack themselves, without any overhead and lengthy introductions. I have found out that the Sprinkle provisioning tool would be the perfect fit for the task.
In fact, just about everything about Sprinkle is awesome. Its language is very clear and elegant. It can install software from source or from packages on every major platform. Its recipes are idempotent, ie. when you set the “verification” conditions properly, you can run the installer over and over again and it will install only the missing pieces. It can install software remotely equally well as locally. Its source code is a great exercise in well designed and well written Ruby library.
So, I went with Sprinkle.
Attendees needed only Ruby and RubyGems on their local machines. After cloning the repository with recipes, they have installed various Rails stacks on their own, fresh Ubuntu VPS in matter of minutes.
Sprinkle recipes are concise, understandable and clarify the relations between various pieces of a Rails stack. Take, for instance, the definition of a classic Apache/Passenger stack:
Notice how the Sprinkle recipe definition clarifies what components are needed at all, so you can base your explanations and whiteboard schemes on them.
The configuration for the stack is comparably simple to follow:
That is extremely convenient, because you can use the same instructions to explain what you need to run a Rails application, how theese pieces work together, and to actually install them on a server via provisioning tool, while talking about all of that. (And you have another argument for Ruby’s syntax superiority, of course.)
To put it another way, Sprinkle recipes can be understood as executable instructions in the same sense as RSpec or Shoulda tests can be understood as executable specifications.
I am absolutely convinced that I couldn’t explain everything any other way; after a half-day workshop, the operations guys walked away with 100% understanding how hosting Ruby on Rails works, what are the alternatives and their advantages, and they can continue their explorations with the provided recipes. (The first half of the workshop was dedicated to showing them how developing Rails applications works.)
If you need to explain or teach Rails infrastructure, either on commercial workshops or in education, you may well use and adapt these recipes — please refer to the Readme how to use them.
Nevertheless, I tried hard for encouraging best practices of hosting web applications, so you’ll find eg. Apache and Nginx correctly configured with expires headers for static assets or gzipping text responses. Thus, you can use the recipes for provisioning a real box as well.
After you install one of the stacks, a place for your Rails applications is created in /var/applications. To actually check out if the stack works, create a simple demo application. Connect via SSH to the box and run:
$ cd /var/applications
$ rails new demo
$ cd demo
$ rm public/index.html
$ rails generate controller welcome index
Now, put something like render :text => 'Welcome'! inside the app/controllers/welcome_controller.rb, and uncomment the root :to => "welcome#index" route inside config/routes.rb.
You should see your new demo application’s greeting when you load the server IP or hostname in a browser. And it probably took 15 minutes or less.
Rails had, historically, bad reputation in terms of deployment simplicity. As you can see, that is really a thing of the past. Whether you’re deploying to Heroku, Engine Yard, or your own server, the Ruby community has done a wonderful job of smoothing all the hard edges.