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: http://blog.tyraeltong.com/blog/2011/10/04/getting-nginx-plus-passenger-work-with-rvm-gemset/ and http://everydayrails.com/2010/09/13/rvm-project-gemsets.html
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:
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:
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.