Getting Started With RVM: Features To Use and Pitfalls To Avoid·
There is a lot of old, outdated, and just plain wrong information floating around about RVM (this is the internet after all), so after some requests from you guys, I bring you an overview of RVM: How to get started correctly, what you need to know, and how to use cron and sudo.
What is RVM?
RVM stands for the Ruby Version Manager. It is a piece of software that separates your entire Ruby environment in to component parts, separating your interpreter, installed RubyGems, and even docs. This lets you switch between different projects at will and use different versions of Ruby and different sets of gems at will.
Why use RVM?
In addition to managing Ruby versions (for which it gets its name), RVM also provides other features such as gemsets. This allows you not only to segregate Ruby versions, but also different versions of gems between two projects. The classic example of this sort of usage is where gems are not compatible as in Rails 2 and Rails 3.
Additionally RVM allows you to create a per project
.rvmrc file. This lets you change the settings of RVM per single project and directory, preventing you from having to remember to manually set your Ruby version for each project that you’re working on.
So, how do I get it?
Now that you know what RVM can do, you can install RVM with a simple one liner:
curl -L https://get.rvm.io | bash -s stable --ruby
This will get your Ruby 2.0, but if you prefer 1.9.3 or some other version you can specify that as well:
curl -L https://get.rvm.io | bash -s stable --ruby=1.9.3
Don’t worry too much about what version you pick right now, that is one of the features of RVM, you can always add another version later.
Once everything is installed you’ll get a message from RVM saying something like:
* To start using RVM you need to run `source /Users/twood/.rvm/scripts/rvm` in all your open shell windows, in rare cases you need to reopen all shell windows.`
This simply executes the
.rvm/scripts/rvm file in the current shell, as in bash the source command is synonymous with
Once that is complete you can check to see that RVM is installed with
rvm info which will give you information about your current setup including binaries, environment variables, and system info. If you’d like you can also do
rvm notes to view version notes.
Now is also a good time to check your current Ruby version as well with
ruby —version which should match whatever you specified at install time. RVM refers to each version of
ruby as Rubies. If you want to install other Rubies you can do so now with just a few steps. For example if you’d previously install 2.0 and would now like to use 1.9.3 you’d simply:
rvm install 1.9.3 rvm use 1.9.3 rvm rubygems latest
This would allow to have Ruby version 2.0 and 1.9.3 installed. To switch between the two, simply tell RVM which one you’d like to use:
rvm 1.9.3 or
rvm 2.0 which is short for
rvm use 1.9.3 and
rvm use 2.0 with the only difference being a confirmation message at the terminal.
Keep in mind that if there is not a binary version available the install time will be significantly longer as the Ruby version will now need to be built from source. To see what Rubies you have installed simply use:
This is all fine and good if you’re after a specific version, but RVM even provides a way to list off all the available Rubies:
rvm list known (53 versions at the time of this writing).
Now that you have all the versions that you want installed, its time to pick a default, otherwise you’ll have to set your new version every terminal session, not productive. To check your default you can use
rvm list again and you’ll see something like the following:
$ rvm list rvm rubies =* ruby-1.9.3-p429 [ x86_64 ] ruby-2.0.0-p195 [ x86_64 ] # => - current # =* - current && default # * - default
Now to change your default all you need to do is use the
—default switch as in
rvm use —default 1.9.3. So fare we’ve only used the
As mentioned above RVM provides the ability to create per project
.rvmrc files that alter the gemset and Ruby version that RVM uses automatically. For example if you have a project in your
~/projects/my187project that you want RVM to use Ruby 1.8.7 for you can do:
cd ~/projects/my187project rvm —rvmrc —create 1.8.7@my187project
There are many options you can set in your
.rvmrc file, for the full list see the .rvmrc documentation.
RVM and Gemsets
Because RVM completely separates your Ruby setups in to independent entities your ruby executable, gems, and irb are self contained as well from each other and from the system and you can have separate named Gemsets.
For example you can have a testing gems set by using: $ rvm gemset create testing gemset created testing => /Users/twood/.rvm/gems/ruby–1.9.3-p429@testing
We can then go ahead and switch to this gem set using
rvm 1.9.3@testing and install gems (e.g.
gem install rails). Note that we don’t use
sudo to install gems. This brings us to the next point:
RVM and sudo
By now you know that RVM creates separate gem directories for all of your Rubies and that you can have different named gemsets, but a consequence of this is that you DO NOT use sudo when working with RVM gems. This is because running
sudo is the same as running another shell as the root user causing all the RVM setup (including environment variables) . As the RVM documentation puts it “You will start to think that someone has a voodoo doll of your application…”
RVM with Cron
When you schedule a job with Cron, at the specified time the system will launch a shell (usually
/bin/sh) with a specified
$PATH listed in
/etc/crontab. As you may imagine this means that all of the setup that RVM has done is inaccessible to cron. If you really want to see this in action you can add the following job to cron:
* * * * * env > /tmp/cron_env
Once you see ’/tmp/cron_env
get created, kill the job, and compare the file to you runningenv` yourself. Now you really see the issue. Fortunately thre is a way around this.
Use RVM wrappers
RVM provides a wrapper for every installed ruby and gemset that allows for usage with command-line tools such as gem, rake, and ruby. If you want to take a look at them, they live in
$rvm_path/bin. We can take advantage of this fact and use these wrappers to craft cron jobs that will have the correct environment. So for example if we are using the ruby ruby–1.9.3-p429@my_project then we can create a cron job like the following:
1 15 * * * /usr/local/rvm/bin/ruby-1.9.3-p429@my_project /path/to/my/script.rb
Note that you can also load the environment from a separate shell script now that you know where it lives, but I personally prefer this option as it makes it clear whats going on when I edit my crontab.
We’ve now gone over the basics of how to use RVM to customize your Ruby environment. For beginner to intermediate day to day use you should be good to go from here, but there is a lot more to RVM than listed here. If you want to know more, just send me an email and I’ll do my best to answer your questions or address them in a future blog post. The RVM documentation is invaluable and can be found here.