Ruby is an extremely flexible, concise
language which boasts a rampant proliferation of libraries and popular
frameworks like rails. However, using your system’s default ruby to
install gems is a quick path into dependency nightmares, as different
gems fight to use different versions of the same library.
I’ll walk you through how to avoid this using
Install
Ubuntu note: Use
Note I previously recommended adding
When you’re done installing rubies, run:
You may have noticed that
~/.gemrc
This will prevent gem from installing local documentation for each
gem it installs which, honestly, you aren’t going to read anyway. This
makes
Install
Now that we have ruby, we’ll want to install some gems. After all,
managing gems is the whole reason we embarked on this journey.
Fortunately, ruby-build already installed
Now hop into your project and type:
Note: You’ll need to perform
Using
The tricky bit with bundler is that we’ve probably installed several
versions of a gem. Which one do we use, and how do we locate it on the
Rather than running
If you’re only consuming apps and libs it should be sufficient to run
Since typing
Check whether rvm is in your path, and if so, remove it from your path and delete rvm using
Check whether you have more than one ruby installed:
If system ruby is still there when you’re done, uninstall all gems from system ruby:
Shell
I’ll walk you through how to avoid this using
rbenv
, ruby-build
, and bundler
.
At the conclusion, you’ll have a better understanding of where ruby
lives on your system and you’ll also have a stable, flexible ruby
installation that can grow with new development while simultaneously
providing a bulletproof runtime environment for existing applications
and tools.Questions Before we Begin
- What about RVM?
RVM is another tool that purports to alleviate ruby’s dependency issues. Having used bothrvm
andrbenv
on OSX, CentOS, and Ubuntu, I findrbenv
to be simpler and more reliable. - I already have some ruby stuff installed. What do I do?
Skip to the “Resetting Your Ruby Installation” appendix at the end of this article. Once you’re done, return here and proceed onward, to glory!
Prerequisites
In order to installrbenv
and ruby-build
you’ll need git and a c compiler. On *nix you can usually get the c toolchain via the build-essential
package. On Mac, the c compiler comes from Xcode or the CLI tools for Xcode, which is a much smaller download.
Install rbenv
rbenv
or “ruby environment” is a CLI tool that enables
you to quickly and easily switch between different rubies installed on
your system. We’re also going to install ruby-build at the same time.Ubuntu note: Use
~/.profile
instead of ~/.bash_profile
below. Also, we’ll need to install some dependencies first:$ sudo apt-get install -y libssl-dev zlib1g-dev libreadline-dev
On to the rest!$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
rbenv
and ruby-build
are now installed. If you’d like to learn more about rbenv
or ruby-build
, refer to @sstephenson’s docs – they’re top-notch.Note I previously recommended adding
RUBY_CFLAGS="-march=native -O3"
to your .bash_profile
to make ruby faster, but this caused some issues in later versions of ruby so if you have it there now, take it out.Installing a ruby
Oncerbenv
and ruby-build
are installed you can install a ruby:$ rbenv install --list
To see a full list of available rubies, or for popular rubies (at the time of writing):$ rbenv install 1.9.3-p392
$ rbenv install 2.0.0-p0
This will download the source, compile, and install ruby, which will
take a few minutes depending on your internet connection and CPU.When you’re done installing rubies, run:
$ rbenv rehash
Switching between rubies
Once at least one ruby is installed, you’ll want to set it as the global default so you have a ruby available for doing fun ruby things:$ rbenv global 1.9.3-p392
$ ruby -v
ruby 1.9.3p392 (2013-02-22 revision 39386) [x86_64-linux]
$ rbenv global 2.0.0-p0
$ ruby -v
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]
If one of your projects requires a specific version of ruby, you can specify this by running rbenv local VERSION
inside the project directory. This will drop a .ruby-version
file into your project, which you can check into source control. That way the version constraint is shared with your team.You may have noticed that
which ruby
doesn’t really work
anymore since it just points to the rbenv shim. If at any point you’re
not sure which ruby you’re using, type rbenv version
to see.Configure Gem
Create~/.gemrc
with the following contents:1 2 |
|
gem install
run much more quickly and use less space.Recap So Far
We’ve installedrbenv
, compiled a version of ruby using ruby-build
, and set our default ruby. We have rbenv
installed under ~/.rbenv/
and rubies under ~/.rbenv/versions/
. We added a .gemrc
to keep our gems lean.
Install bundler
Now that we have ruby, we’ll want to install some gems. After all,
managing gems is the whole reason we embarked on this journey.
Fortunately, ruby-build already installed gem
for us. Now we need bundler
.bundler
is a tool that allows you to install multiple
gem versions side-by-side, and sandboxes each project so that its gem
dependencies don’t conflict with other projects. Additionally, bundler
allows you to deterministically re-install all of your project depenencies on other developer machines, on production, etc.$ gem install bundler
$ rbenv rehash
We need to run rbenv rehash
any time we install (or remove) an executable like rake
, bundle
, etc. or a new ruby version. This makes rbenv rebuild all of the shims used to launch those executables.Now hop into your project and type:
$ bundle install
bundler
will examine your Gemfile
and install all of the listed dependencies.Note: You’ll need to perform
gem install bundler
for each version of ruby you install.
Using bundle exec
The tricky bit with bundler is that we’ve probably installed several
versions of a gem. Which one do we use, and how do we locate it on the PATH
? We don’t. bundler
does this for us.Rather than running
rake
from the terminal, we’ll run:$ bundle exec rake
This ensures that the version of rake that’s tied to our application
is the one that gets executed, even if we have 5 versions on our system.
If you’re not in a project context (i.e. there’s no Gemfile
in your directory), feel free to call rake
from the terminal.If you’re only consuming apps and libs it should be sufficient to run
bundle install
and bundle exec
, but if you’re writing ruby code you’ll probably find the bundler docs very useful.Aliasing
From now on, just remember to runbundle exec rake
instead of rake
and you’ll be completely sandboxed. You’ll never have a project stop
working because you installed another version of a gem somewhere else.Since typing
bundle exec
is somewhat verbose, you can create an alias
like be
or bex
or similar to make life easier.$ alias bex="bundle exec"
$ bex rake
You can add this to your ~/.bash_profile
or similar to make it persistent.Appendix A: Resetting Your Ruby Installation
“Help! I have a (messed up) ruby installation already!”The following steps will help you remove rogue rubies from your system. This is potentially destructive. You have been warned.
Check whether rvm is in your path, and if so, remove it from your path and delete rvm using
implode
.$ echo $PATH | grep rvm
$ rvm implode
If you prefer, you can move ~/.rvm
somewhere else to back it up, or rm -rf ~/.rvm
. Restart your terminal after this is done.Check whether you have more than one ruby installed:
$ which -a ruby
If you’re on Mac, remove all rubies except system ruby, which installed at /usr/bin/ruby
.
System ruby ships with OS X and removing it will cause Bad Things to
happen. If you’re on linux, you can safely remove all rubies using your
package manager, or rm
if you installed them some other way.If system ruby is still there when you’re done, uninstall all gems from system ruby:
yes | sudo gem uninstall -a --ignore-dependencies `gem list --no-versions`
Restart your terminal so everything is flushed. At this point, you should be able to type:$ which ruby
$ which gem
$ gem list --local
And see /usr/bin/ruby
and /usr/bin/gem
on Mac, or nothing on Linux.Shell
yum --enablerepo=rpmforge,epel,remi -y install gcc make zlib zlib-devel openssl-devel zshcd /usr/localgit clone git://github.com/sstephenson/rbenv.git rbenvmkdir rbenv/shims rbenv/versionschgrp -R groupname rbenvchmod -R g+rwxXs rbenvgit clone git://github.com/sstephenson/ruby-build.git ruby-buildcd ruby-build./install.shcat << _ZSHCONF_ >> ~/.zshrc## rbenv configexport RBENV_ROOT="/usr/local/rbenv"export PATH="/usr/local/rbenv/bin:${PATH}"eval "$(rbenv init -)"_ZSHCONF_rehashrbenv install 1.9.3-p392rbenv global 1.9.3-p392rehash