Using project specific gemsets with Rails, RVM and Passenger

I ran into an issue the other day that was exacerbated by the fact that blog posts on the subject seemed to be out of date. Therefore, this is an attempt to bring a more up-to-date solution.

You may have this issue if you use Passenger with Nginx or Apache for your ruby server, and you also use rvm and gemsets to isolate the gems for a given project. When building the passenger gem, it uses the current gemset and ruby version as the one that will be added to the nginx or apache configuration. This is fine for a production server, which is only going to have a single project, but if you use it for development then you'll want to change between multiple projects and therefore multiple gemsets. Here's how you do it.

Note: a Google search brings up the following blogs, which are now outdated because of updates to RVM: and

Don't use RVMRC

First of all, don't use a .rvmrc file, as this has now been superceded by .ruby-gemset and .ruby-version files, which are less dependent on the ruby manager. If you're using a recent version of rvmrc (i.e. 1.2+) then you should get a warning anyway.

Create a version and gemset file

You do this with the rvm use command, replacing "ruby" and "gemset" with the corresponding names:

$ rvm --create --ruby-version use ruby@gemset

This creates the two files in the current directory, specifying which ruby and gemset to use.

Tell rails to use the new gemset

Create a file at config/setuploadpaths.rb, which contains the following:

if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm')
    require 'rvm'
    RVM.use_from_path! File.dirname(File.dirname(__FILE__))
  rescue LoadError
    # RVM is unavailable at this point.
    raise "RVM ruby lib is currently unavailable."

You may have seen similar code from older blog posts - these manipulate the load path to include the RVM lib path. This is no longer necessary in newer rvms.

Restart RAILS

Just restart, and it passenger should now be using the new gemset. Note that the app must always use rvm, because of the new file we added to the configuration. If you're deploying to a different environment (which is inadvisable anyway) then you will need to catch the LoadError and handle it differently.

← Previous post: Copying between tmux buffers and the system clipboard Next post: Using the pessimistic version constraint operator with ruby gem versions →
comments powered by Disqus