29
votes

Following current best practices, what is the proper role for each of these?

Based on my limited understanding of Bundler and RVM, it seems that they--like Rubygems--have their own install locations for gems. Plus, for each one, there's the option of installing to system paths using sudo or to your home directory. And then there's the ability to vendor gems with Bundler (where applicable, e.g. with Rails).

So it looks to me like there are at least seven places to install gems now:

  • Rubygems system path
  • Rubygems user path
  • RVM system path
  • RVM user path
  • Bundler system path
  • Bundler user path
  • Vendor (per-app)

So, what's the best way to manage all this? Do we use all three (Rubygems, Bundler, RVM) and tell them all to install gems to the same place? Do we use sudo all the time, some of the time, or never? And should we be using a different strategy on production and development machines?

On a related note, are Bundler and RVM wrappers around Rubygems, are they alternatives to it, or are they completely orthogonal to it?

2

2 Answers

33
votes

From Bundler's website:

Bundler makes it easy to make sure that your application has the dependencies it needs to start up and run without errors.

This means that it's trivial for some other developer, or you on another machine, to get ready to develop further or use it, by running bundle install and you have everything you need to get up and running.

RVM is for managing multiple versions of Ruby on the same machine, and switching between them. Gemsets is a powerful feature RVM provides that isolates gems for one application/library from the rest of your system.

When using RVM and Bundler together, RVM tells Bundler where the gems should go, and Bundler installs them into the RVM-folder.

Both (with regards to gems in RVMs case) use and depend on Rubygems, so they're closest to wrappers.

I, personally, use Bundler and RVM for all my projects. No gemsets, just Bundler to resolve and fix things, which it does without fail. Installing gems is done without sudo, and ends up in the place RVM defines. The default Ruby install on my system is left alone, and nothing is installed to Rubygems system/user path

3
votes

The way I do it now (still experimenting a bit though) is this:

  1. Use RVM to set up the ruby version and a gemset to use for an app. I use an .rvmrc-file in the root of the app directory to make sure the correct ruby and gemset is used all the time.

  2. Bundler is installed using gem without sudo in the given gemset.

  3. Any gems needed by the app is added to the apps Gemfile and installed using Bundler. I'm not using sudo for this.

This way I use Bundler to keep track of the dependencies for each app, and RVM to isolate each app's gems from each other. Works really smooth, actually.

I have not yet installed RVM on my deployment server, there I just use Bundler to make sure each apps dependecies are handled. I will probably install RVM there as well, but have to figure out how that plays ball with Passenger first.

As for your last question, Bundler is a wrapper around gem, RVM just manipulates the gempath where gems are installed. It seems to be smart enough that it picks up the gems from the same place though so I don't need to recompile any that are already installed in some other gemset.

I've stopped using sudo for installing gems after starting to use RVM. There's really no reason over just installing them in the rvm user path. I'm unsure about the best practice if you have more developers on the same machine like a test server or something like that.