Notes to self

Installing Ruby with ruby-build and ruby-install

When you need a unified way to install CRuby and alternative Ruby implementations these days, it comes down to ruby-build and ruby-install. Is there a difference?

Ruby installers

A lot of people associate Ruby version managers and installers to be the same thing. One of the most popular Ruby version manager, RVM, does both, so that’s not surprising.

rbenv changed this assumption by simply focusing on a better way of switching rubies (by not replacing cd in your shell with a shell function), leaving the task of getting and compiling Ruby to be a separate problem.

Read the Hacker News announcement of rbenv for nostalgia. It’s worth noting that rbenv came from folks from 37signals, now Basecamp and Hey, the company behind Ruby on Rails (originally written by Sam Stephenson).

This change of perspective gave birth to ruby-build. If installed as an rbenv plugin, it does the installation part for rbenv users. But at the same time, ruby-build is also a standalone program that can “just” install Ruby on your system.

Later on, chruby came as the simplest alternative to switching Ruby. And it came with ruby-build alternative called ruby-install as it’s a sister project for installing your rubies.

If you are looking for a simple way to install Ruby or JRuby, which one to choose today?

ruby-build

ruby-build (at the time of version 20200926) can be installed as:

$ git clone https://github.com/rbenv/ruby-build.git
$ PREFIX=/usr/local sudo ./ruby-build/install.sh

I am not aware of prebuild system packages (such as RPM or DEB).

The usage is simple:

$ ruby-build --definitions             # lists all available versions of Ruby
$ ruby-build 2.7.1 ~/local/ruby-2.7.1  # installs Ruby 2.7.1 to ~/local/ruby-2.7.1

Besides the obvious, ruby-build can:

  • install Ruby, JRuby, mruby, TruffleRuby, Rubinius, REE, Topaz,
  • apply patches,
  • verify checksums,
  • and use custom build configuration

A small inconvenience is that ruby-build won’t handle the installation of any system pre-requisites such as C compiler and these have to be installed beforehand.

On Fedora with:

$ dnf install -y gcc make bzip2 openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel autoconf bison ruby -y

Note I needed to add autoconf, bison, and ruby to the official list if I wanted to buld -dev versions of Ruby. Why Ruby you ask? ruby-build builds -dev versions from the GitHub repository and thus needs Ruby for the ./configure step:

configure: error: cannot run /bin/sh tool/config.sub

This would not be needed when building from published archives.

A notable configuration change that many will want to do is to configure CRuby to use jemalloc (by passing --with-jemalloc to the ./configure step). This can be done with:

$ RUBY_CONFIGURE_OPTS=--with-jemalloc ruby-build 2.7.1 ~/local/ruby-2.7.1

Similar to basic build packages, jemalloc would need to be installed as well. On Fedora:

$ sudo dnf install jemalloc-devel -y

The latest development version of Ruby (also called “trunk” or “HEAD”) can be installed by appending -dev:

$ ruby-build 3.0.0-dev ~/local/ruby-3.0.0-dev

All in all, ruby-install keeps things very simple. Apart from rbenv we can find it also powering the Ruby plugin for asdf (general multi-tool version manager). This makes it even more popular than it already is.

ruby-install

ruby-install (version 0.7.1) can be installed as:

$ wget -O ruby-install-0.7.1.tar.gz https://github.com/postmodern/ruby-install/archive/v0.7.1.tar.gz
$ tar -xzvf ruby-install-0.7.1.tar.gz
$ cd ruby-install-0.7.1/
$ sudo make install

For Fedora users, ruby-install (together with chruby) seems to be available as an RPM package on Copr. Note that there was an official Copr, but it seems discontinued for the time being.

The usage is similarly very simple:

$ ruby-install ruby # install latest stable Ruby
$ ruby-install --latest # lists all available versions of Ruby
$ ruby-install --install-dir ~/rubies/ruby-2.7.1 ruby # sets specific install dir

You can also use it for installing Ruby versions for RVM or rbenv by simply changing the paths to the following:

$ ruby-install --rubies-dir ~/.rvm/rubies ruby 2.7.1 # RVM default path
$ ruby-install --install-dir ~/.rbenv/versions/2.7.1 ruby 2.7.1 # rbenv default path

It can:

  • install Ruby, JRuby, mruby, TruffleRuby, and Rubinius.
  • apply patches,
  • verify checksums,
  • use custom build configuration
  • and even install dependencies via various system package managers

The list of what it can do is almost the same, unlike ruby-build it has default directories set and can use APT, DNF and brew to install what’s needed.

Very interesting is the anti-feature of not requiring update every time a new Ruby version comes out (ruby-build keeps all version recipes in share/ruby-build). You might need an update if the new Ruby version has new requirements, though.

It might also be a reason why ruby-install unfortunately does not support installing trunk/HEAD, which is the only thing lacking behind ruby-build – but you can still install official previews such as 3.0.0-preview1.

A custom build configuration for the ./configure step can be passed after the command itself:

$ ruby-install ruby 2.6 -- --with-jemalloc --enable-shared CFLAGS="-O3"

jemalloc is unfortunately not install automatically as other system dependencies for now so make sure to install jemalloc with header files (jemalloc-devel package on Fedora).

My choice

As you can see, both ruby-build and ruby-install “do the trick.”

I would recommend choosing ruby-install for:

  • your everyday development
  • and building a production box
  • users of chruby, the most minimal and fastest Ruby switcher

…mainly due to:

  • not requiring updates for every new release,
  • conveniently installing system dependencies (apart from jemalloc for now),

I also recommend ruby-install for deployment in my book Deployment from Scratch.

I would stick to ruby-build if:

  • I am already a user of rbenv or asdf for development
  • or need to be building bleeding edge rubies
Check out my book
Deployment from Scratch is unique Linux book about web application deployment. Learn how deployment works from the first principles rather than YAML files of a specific tool.
by Josef Strzibny
RSS