While our Moonshine is still distilling, I’d like to present some examples of using existing automation tools to deploy Rails applications easily.
When Jamis Buck released Switchtower (now known as Capistrano) around 3 years ago, automated Rails deployment become standardized. It was a historic moment in Rails history. Since then, Capistrano has been used for a number of tasks beyond code deployment related to system configuration and automation. The railsmachine gem provides tasks for configuring an application stack. However, our gem has always assumed that you were deploying against a golden image (or foilball) and only addressed configuration. Other Capistrano-based projects took the additional step of automating calls to package installers to setup an empty machine. All of these projects provided a quick way to deploy a Rails application on a new server. Despite their utility, the approach has a number of shortcomings: increased code complexity, not idempotent, difficult to model complex dependencies, only executable via cap, difficult to manage existing systems, etc. When all you have is Capistrano, everything looks like a cap task.
With the rise of the clouds, automation tools are getting a lot attention recently. Unbeknownst to most developers, sysadmins and operations folks have been using an automation tool called Puppet for the past few years. Puppet is written in Ruby and provides its own external DSL and services for managing infrastructure. In addition, the new, Puppet-inspired Chef is helping spread the gospel of automation to Rails developers. More awareness is a good thing. Automation is a best practice that all Rails developers should add to their development process.
Cheese and Crackers
By using using Puppet with Capistrano, we can use the right tools for the right job. The issue of how to partition the work between the two tools has been been recently discussed by Andrew Shafer of Reductive Labs. Although I think we can push more onto Puppet then Andrew suggests, we both agree when Adam Jacob writes: Capistrano and Puppet go together like cheese and crackers.
One of our current goals is to easily integrate server automation into every Rails deployment. The challenge is that existing tools are just frameworks and have no knowledge or opinion on deploying Rails applications. Some developers will take the time to learn the tools and others won’t. This is understandable since spending time learning about automation frameworks is time not spent developing revenue-generating features.
To jump start the process, I’ve written an example called shadow_rails that can be used as a starting point for introducing automation into your existing deployment process. The code is written using ShadowPuppet to install packages and configure the system. The tricky part is that Ruby-based automation tools require ‘ruby’. Therefore, there is a little bootstrapping script to install Ruby Enterprise Edition from source or the Ubuntu 8.10 ruby packages. In addition, shadow_rails installs Apache, MySQL, Passenger, and Rails. It configures Apache, creates your database, and sets up the Capistrano directories. From the comfort of your development box, you can go from nothingness to a deployed app in one command:
cap deploy:bootstrap deploy:migrations.
This project is meant to help you get going with using automation and not the final word in deployment. To get started, read the README in the GitHub repository. Clone and browse around the code to get familiar with the syntax. Fork the code and try to make it work for your application. There are even a few rspec examples written using ShadowFacter for those interested in exploring behavior driven automation.
You’ll need a fresh install of Ubuntu 8.10 with an admin user named ‘rails’ and ssh installed. I highly recommend using a virtualization tool like VMware Fusion on OS X or VMware Player on Ubuntu for testing. Using snapshots and rollbacks, testing your manifest is super easy for both clean installs and existing ones as the manifest evolves.
Please let me know what you think and ping me with any questions. If you are a Rails Machine customer and would like to try it on a new virtual machine, please submit a ticket.