Isolate your Ruby environment

on captainepoch's log

Developers normally have a few environments while making a software (for a company, as an indie dev…) that isolates all the dependencies in order to get the product to work.

I was interested on that a few days ago. I was asking myself if it is another way to get isolated enviroments for hardcore stuff like C or C++, where libs are normally installed with the package manager you are using or by compiling them within the source code or as a static binary. With Python you can use virtualenv, which created isolated environments and then you can deploy. There are a few for Ruby, but I am going to use RVM.

I am not a Ruby developer. I do not know a thing about this programming language. I was looking for a way to have the same set up for Jekyll that I got on my server, because I wanted to make some modifications to the minima theme (It came as a gem and, if I modify inside of the gem, when I update it is not going to be the theme with my modifications) and not with the system’s Ruby version.

So, let’s get started!

DISCLAIMER: I will be doing this post on a Debian 8.3 machine with testing (stretch) repositories. I did on my ArchLinux machine and it works like a charm. I did not try on Mac OS X but it should work.

Installing RVM

First of all you need to install rvm. Going through its website you see a gpg import key command. Do not do it. If you do, then the curl command let you know that you should import another key, so execute the curl command first.

$ curl -sSL https://get.rvm.io | bash -s stable

You will be asked to import a gpg key, so do it and execute the command again. If it does not work, try the second command it appears:

$ curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -

I did it once because the gpg2 command does not work and it works.

If you are using zsh as a shell, please read the comments you will get, because you need to do it in order to get rvm working. I put this at the end on my .zshrc file and it works:

if [[ -d "$HOME/.rvm" ]]; then
    source ~/.profile
fi

Then, close and reopen your terminal, and type:

$ rvm --version

And you should see something like that (with the version you installed):

$ rvm 1.27.0 (latest) by Wayne E. Seguin <wayneeseguin@gmail.com>, Michal Papis <mpapis@gmail.com> [https://rvm.io/]

Installing a Ruby version

With RVM you can manage a lot of versions of Ruby. In this post it will be 2.3.1, the latest at this moment, but you can have MRI/YARV, JRuby and Rubinius too.

Before installing anything about Ruby, let’s check if the requirements are installed, so execute:

$ rvm requirements

It installs every dependency to compile and install Ruby and get everyting working. You have to have sudo permissions.

After installing everything, let’s get to install a Ruby version, so:

$ rvm install RUBY_VERSION

Where RUBY_VERSION means the version you want to install. In my case, it will be 2.3.1.

You can use whatever version of Ruby you want. I will be using the latest because I use it with Jekyll. If rvm does not find any binary for that version, it will compile, so first you should check the requirements.

Using a version of Ruby

In order to have a version running as default, you have to execute the command to set it default:

$ rvm use RUBY_VERSION --default

Where RUBY_VERSION means the version you installed. This is going to set the necessary variables to use that version of Ruby on your user, not on the system. In my case it is going to be 2.3.1 as I said.

You can change it whenever you want for another version of Ruby you installed.

Create a gemset

A gemset is not more that a set of gems for an specific version of Ruby. Let’s create one:

$ rvm create gemset GEMSET_NAME

The GEMSET_NAME will be jekyll321 because I will use Jekyll 3.2.1 as an example. You can create the gemset with the name you want to, even create more than one gemset at a time, but it is not tue purpose of this post:

$ rvm gemset create GEMSET_NAME1 GEMSET_NAME2 ...

You have more information about gemsets at its Basics page.

Installing gems

To choose the gemset you have created, execute:

$ rvm RUBY_VERSION@GEMSET_NAME

Where RUBY_VERSION is the version of Ruby of your choice and GEMSET_NAME is the name of the gemset you want to use. In my case it will be 2.3.1 and jekyll321.

After that, you can install gems right know. I will do with Jekyll right now.

Isolating the environment

Right now you have everything you need to start blogging with Jekyll, and that is cool! But it is not completed. In order to achieve that first you need to create a blog and then set the files to use only that version of Ruby and that gemset.

Once you created your blog with Jekyll and you navigate into the folder, you will notice a message that says:

RVM used your Gemfile for selecting Ruby, it is all fine - Heroku does that too,
you can ignore these warnings with 'rvm rvmrc warning ignore [directory]/Gemfile'.
To ignore the warning for all files run 'rvm rvmrc warning ignore allGemfiles'.

Unknown ruby interpreter version (do not know how to handle): RUBY_VERSION.

And that is correct, because it means you (and me) installed everything correctly. But it presents a problem: you lost your gemset. If you try to execute some commands of Jekyll, it fails, so assign again as in Installing gems.

Then you are going to create two files: .ruby-version and .ruby-gemset. The first file will indicate which version of Ruby you will be running, and the second the gemset you want to use. Those files will contain information about what it should used by Ruby. Into the directory of your project execute:

$ rvm --ruby-version use RUBY_VERSION@GEMSET_NAME

--ruby-version will create two files that are compatible with others Ruby virtual environment managers such as rbenv. As always where RUBY_VERSION is the version of Ruby of your choice and GEMSET_NAME is the name of the gemset you want to use. In my case it will be 2.3.1 and jekyll321. You can now delete the Gemfile if you have what you need in your gemset.

And that is it! You got a isolated environment for Jekyll (in this case). You can create some of them with the gemsets and the Ruby versions.

Using a hook to generate the blog

You may notice, if you are using the post-receive hook to generate the blog using git that $PATH is not correctly loaded. To fix it, add at the start of the file:

unset GIT_DIR
source ~/.profile