There are some unexpected and problematic wrinkles around installing user local Ruby “gems” on Fedora and setting GEM_HOME appropriately.

Setting up local user installation is not normally something Fedora users have to worry about, since the Fedora rubygems package has been tweaked so that the gem command automatically performs a local user install when run by a normal user. In particular,

  • Gems are installed under ~/.gem/ruby
  • Executable files are installed under ~/bin

See operating_system.rb for all the gory details.

Ostensibly, this is to make the gem command “just work” without the user having to change their environment. This is all well and good until it breaks something.

If you don’t know about this automatic behaviour, you may have already installed some user local gems without realizing it. For example, you might run

gem install asciidoctor

to install a local version of Asciidoctor. You won’t get a sudo prompt or permission errors, and the new asciidoctor program will be in your path and “just work”.

You could even do something “crazy” like this:

gem install bundler

Bundler is a popular approach to managing collections of potentially conflicting versions of Ruby “gems”.

Why is this “crazy?

The newly installed bundle command is not affected by Fedoras tweaking of the gem command. For example, if you try to use Bundler to install Jekyll with

echo "source 'https://rubygems.org'" > Gemfile
echo "gem 'jekyll'" >> Gemfile
bundle install

you get write permission errors on the /usr/bin and /usr/share/gems directory, since Bundler is trying to perform a system installation.

This is unexpected.

A typical web search will yield an extremely common piece of advice for setting up local user installs. Simply put the following in your ~/.bashrc file:

# Install Ruby Gems to ~/gems
export GEM_HOME="$HOME/gems"
export PATH="$HOME/gems/bin:$PATH"

If you do this, and run either the gem or bundler command as a normal user, then

  • Gems will be installed under ~/gem/ruby
  • Executable files will be installed under ~/gem/bin

This is probably appropriate for Ubuntu and many other Linux systems, but the paths are wrong for the default Fedora. If we don’t correct that, then bunder and gem are going to install to different locations.

We could (blindly) follow the above advice to get bundler to work. If we then run

gem install jekyll

a second version of Jekyll is installed under ~/.gem/ruby, but the jekyll command still uses the original one under ~/gems. This is unexpected. Similar confusion arises with the gem uninstall command.

Initially this is fine, but becomes problematic as the versions of the dependencies diverge, and can take a while to sort out, especially if you are installing many user local gems over a long time.

To get mutually compatible behaviour on Fedora, simply add the following to your bash configuration:

# Install Ruby Gems to the default Fedora locations
export GEM_HOME=$HOME/.gem/ruby
if [[ ! -e $HOME/.gem/ruby/bin ]]
then
    ln -s $HOME/bin $HOME/.gem/ruby/
fi

Your ~/.bash_profile is probably a more sensible place to put this, rather than .bashrc, since the former only gets sourced once on login, whereas the latter gets sourced for every sub-shell.