Michael Trojanek (relativkreativ) — Bootstrapper and creator of things

This article was published on March 30th 2016 and takes about 5 minutes to read.

Use it with caution — it is probably still valid, but it has not been updated for over a year.

How to automate rbenv installations

A question that pop ups every now and then in various forums is how to automate rbenv installations. This may seem more complicated than it is — once you know how rbenv works, it is actually pretty easy.

For those that do not know, rbenv is an awesome Ruby version manager. It allows you not only manage Ruby installations with ease but also to painlessly switch between different Ruby versions and even run multiple Ruby interpreters in parallel.

This makes it essential for development environments as well as for production where running multiple Ruby (or especially Rails) applications in parallel with different Ruby versions is essential.

How to install rbenv following its documentation

If you are developing on a Mac, the easiest way to install rbenv is via Homebrew — run brew install rbenv and you're done.

However, in order to understand how rbenv really works, you have to install it manually. Fortunately, this is not much harder:

First, clone rbenv from its Github repository into your home directory (the second command compiles the dynamic bash extension to speed up rbenv — don't worry if it fails, rbenv will still work normally):

git clone https://github.com/rbenv/rbenv.git ~/.rbenv
cd ~/.rbenv && src/configure && make -C src

With the repository cloned, we're already halfway through. What's missing is making sure that the rbenv executable is in your PATH and actually loading the rbenv environment when we start a new shell. This is done by adding two lines to your .bash_profile file:

echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
eval "$(rbenv init -)" >> ~/.bash_profile

Automate it

What follows is taken directly from my book Efficient Rails DevOps. If you are looking for more actionable advice like this, you should give it a close look.

Both steps of rbenv's installation are quite easy to automate using your favourite configuration management tool. If you are on my email list or have read one of my books, you will already know that Ansible is my personal favourite (so I'll use Ansible's format here to demonstrate the basic principles) but you will have no trouble to adapt to Puppet, Chef of SaltStack if that's what you prefer.

While we're at it, we will abstract our tasks to be user-agnostic. This means that we can run the tasks for different users (including root) to prepare multiple rbenv environments in one go — just make sure that your configuration management tool substitutes the user variable with the actual user name.

To install rbenv, we already know that we need the git executable as a dependency, so we first make sure that it is available:

- name: Install git
  yum: pkg=git
       state=installed

Then we can clone rbenv into the user's home folder. Do not forget to make this directory (and all files and directories therein) owned by the user we are installing rbenv for:

- name: Clone rbenv repository
  git: repo=https://github.com/rbenv/rbenv.git
       dest=~{{ user }}/.rbenv
       update=no

- name: Set correct owner and group
  file: path=~{{ user }}/.rbenv
        owner={{ user }}
        group={{ user }}
        recurse=yes

Instead of editing each user's .bash_profile file, I like to create a script in the /etc/profile.d directory to keep things DRY (scripts in this directory are run for each user on login).

We can use a little custom script (called rbenv.sh) that checks for existence of a .rbenv directory in a user's home directory. If that's the case, the script manipulates the user's PATH and initializes rbenv (as explained above):

#!/bin/sh

if [[ -e ${HOME}/.rbenv ]]; then
  export PATH="${HOME}/.rbenv/bin:${PATH}"
  eval "$(rbenv init -)"
fi

This script is placed inside the /etc/profile.d directory:

- name: Install rbenv loader script
  copy: src=rbenv.sh
        dest=/etc/profile.d/rbenv.sh

Once this script is in place, you'll never again have to remember to modify a user's .bash_profile file in order to initialize its rbenv environment.

Install ruby-build

What good is an rbenv installation if we are not using ruby-build to make it dead simple to install Rubies?

Before we can use ruby-build, we have to make sure that its requirements are met. ruby-build itself just needs the git executable (like rbenv does) but in order to actually compile a Ruby version, we need some development packages (the following task targets CentOS/Red Hat systems — if you are using a Debian based distribution like Ubuntu, the packages' names may differ slightly):

- name: Install dependencies for compiling Ruby
  yum: pkg={{ item }}
       state=installed
  with_items:
    - bzip2
    - gcc
    - libffi-devel
    - libyaml-devel
    - make
    - openssl-devel
    - readline-devel
    - zlib-devel

Once all dependencies are met, we can install ruby-build by cloning its Github repository into rbenv's plugin directory and setting the correct owner and group (like we did when cloning rbenv):

- name: Clone ruby-build
  git: repo=https://github.com/rbenv/ruby-build.git
       dest=~{{ user }}/.rbenv/plugins/ruby-build
       update=no

- name: Set correct owner and group
  file: path=~{{ user }}/.rbenv/plugins/ruby-build
        owner={{ user }}
        group={{ user }}
        recurse=yes

Now we are all set — after opening a new login shell we can install a Ruby interpreter with the command rbenv install 2.3.0 (and maybe configure to use Ruby 2.3.0 as default by running rbenv global 2.3.0).

Expand your DevOps skills!

Join hundreds of Rails developers and operators on my email list and get my ebook Build Your Own Rails Server as a free welcome gift.

No spam — guaranteed. You can leave at any time.