production grade ruby interpreter deployment process

rvm, chruby, rbenv, etc. do not belong in a production environment. Even if you are deploying and co-hosting applications that require different versions of ruby those tools still do not belong in a production environment. All those tools are strictly for development environments.

Binary shims and other hacks have no place in a production environment. Ideally you have one user per application that has the proper profile for setting up PATH to point to the right version of ruby which has been compiled and deployed wholesale ahead of time. This is actually quite simple and is in fact a one time operation if you do it right and package the binary bits with an RPM or Debian package. Heck, even a tar file would work if you’re willing to have some extra deployment logic and these days you can use any number of devops tools like chef and ansible to codify the initial production environment setup as well.

Doing things right is actually quite simple. Compiling ruby from source these days is a cinch and the only real hard part is making sure whatever system you deploy to has the proper runtime dependencies but that’s also quite easy these days because of all the modern package managers like apt and yum. Here’s the code that will download, compile, and install ruby on a debian based system. For concreteness sake I’m going to use a specific version but you can substitute any other version. Oh, please also make sure you are doing all this in a VM that matches your production OS/environment as closely as possible. I recommend Vagrant but some people also use qemu for creating an isolated environment. Alright lets get to it.

First make sure you have a clean workspace and the source code for the version of ruby you are going to compile.

Next we are going to install all the necessary build tools and libraries. You should probably change to a root shell for this part. The ./configure options I’ve chosen are just a personal preference and you should pick your own. The ones I’ve chosen work well enough for me.

At this point if you did everything right you should have a version of ruby installed under /opt. To package it you can choose your favorite tool but I personally prefer fpm.

It’s been a while since I’ve done this but that’s the general process for compiling ruby from source and then packaging it for a production deployment. I might have missed a dependency or two but weeding those out is quite simple since you’ll know right away because things will fail with an error about missing shared objects and tracking those down is a simple google search. Combining this with bundler and vendored gems means there is absolutely no reason to install rvm, chruby, or rbenv on machines that are serving production traffic.