captainepoch's log

Isolate your ruby environment

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’s another way to get isolated enviroments for hardcore stuff like C or C++, where libs are normally installed with the package manager you’re 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’re a few for Ruby, but I’m going to use RVM.

I’m not a Ruby developer. I don’t 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’s not going to be the theme with my modifications) and not with the system’s Ruby version.

So, let’s get started!

DISCLAIMER: I’ll 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 didn’t 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. Don’t 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’ll be asked to import a gpg key, so do it and execute the command again. If it doesn’t work, try the second command it appears:

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

I did it once because the gpg2 command doesn’t work and it works.

If you’re using zsh as a shell, please read the comments you’ll 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’ll 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’ll be 2.3.1.

You can use whatever version of Ruby you want. I’ll be using the latest because I use it with Jekyll. If rvm doesn’t 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’s 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’s 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’ve 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’ll be 2.3.1 and jekyll321.

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

Isolating the environment

Right now you have everything you need to start bloggin’ with Jekyll, and that’s cool! But it’s 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’ll 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’s 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’re going to create two files: .ruby-version and .ruby-gemset. The first file will indicate which version of Ruby you’ll 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’ll be 2.3.1 and jekyll321. You can now delete the Gemfile if you have what you need in your gemset.

And that’s 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’re 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

And that’s it!