How to package your entire Rails 3 app into a tarball

Not all Ruby on Rails applications live on the internet within arms length of devops. Some appliations like our own Trisul have to be installed within the enterprise by folks who have no Ruby or Rails skills. A common way to address this use case is to just package the software as a VM image in a format such as OVF – but sometimes the customer just wants to install your package.

This post describes how you can distribute your app as a single tarball containing the correct version of Ruby with all gems and your app bundled. The downside of this approach are :

  1. Platform dependent  – you need to distribute tarballs for major OS and 32/64 bit architectures. We found that between CentOS  and Ubuntu we can hit a majority of users.
  2. Install location is fixed  – your app will install in a common place such as /usr/local/*/{SoftwareName} or /opt/{SoftwareName}/*. The data can be anywhere your app decides to store it.

Without much ado, lets jump right in with an example. We will use a Rails 3 app called Snorby who feel a real world need for this packaging.

Toolbox

The magic ingredient is the most excellent project rbenv written by Sam Stephenson of prototype.js fame. This project allows you to run multiple versions of Ruby by Shimming all your executables. You also need Bundler which includes a command called bundle exec which takes care of running your app within context of a set of Gems

Follow these steps to make the tarball.

  • replace Snorby with your application name
  • replace /usr/local/share with your preferred install area such as /opt

Step 1 – Dev machine

Set aside a development machine which will be used to make the tarball. You also need a pristine machine which you will use to test the tarball.

Step 2 – Install rbenv & prepare the staging area

We will install Snorby under  /usr/local/share/snorby – so we need to install rbenv there

Now add rbenv shell paramaters.Add these three lines to your ~/.bashrc file

Dont worry, the user of the tarball does not have to do this. Just you the package builder.

Close your terminal and open a new one . You are all set to install Ruby

Step 3 : Install Ruby into the staging area

We turn to ruby-build which makes it easy to install various versions of Ruby into specific locations. You could probably do this by hand by compiling from source and using the –prefix switch during compilation.

Install ruby-build

Install your version of Ruby into the staging area

Switch and check ruby version

The ‘rbenv local’ command sets the ruby version for the base directory (/usr/local/share/snorby) to 1.9.2-p290. If you cd to another directory – rbenv switches the version back to the system ruby (or none if there is no Ruby installed)

Step 4 : Unzip your rails app

Unzip your snorby rails app into /usr/local/share/snorby.  Note this should be the Rails.root directory containing your Gemfile.

Step 5 : Install Gems

The first step is to install bundler, which takes care of the rest

The rbenv rehash is required to shim the new bundler executable. Type bundle –version to check if bunder was installed correctly.

Install all your app gems

In case some gems fail to to library dependencies  – install them. For Snorby I had to install 3 dependencies. Once again – dont worry because the end customer doesnt need to do any of this. Thats the whole point of the tarball.

After correcting errors – repeat the following until all gems are installed.

Again dont forget the “rehash”.

You are almost there, check if your apps works in this staging area. Use bundle exec on your rake tasks or start your app.

Step 6 : Startup script

You cant expect the user to be logged on with a custom bashrc in order to start your app. So you need to prepare a tiny startup script which includes the required shell variables at the top.

The trick is to use bundle exec command instead of just command or ruby command.

Step 7 : Tar it

Just tar the whole directory /usr/local/share/snorby

Thats it !

Step 8 : Test it

On a pristine machine of the same architecture test your tarball.

Run your script from Step 6

Hope this helps folks looking to distribute Rails based apps in the enterprise.  Please leave a comment if you think I am missing something.  I feel an improvement can be made by allowing the user to untar to any location – I was never able to get it to work because the library paths are all over the core ruby install.

Author: Vivek Rajagopalan

Vivek Rajagopalan is the a lead developer for Trisul Network Analytics. Prior products were Unsniff Network Analyzer and Unbrowse SNMP. Loves working with packets , very high speed networks, and helping track down the bad guys on the internet.

1 thought on “How to package your entire Rails 3 app into a tarball”

Comments are closed.