Running Multiple Rails Versions by Standalone Gemsets with Passenger


There was a case before that troubled me a lot, I have many projects to run on production server that each one has a different rails version, and each project should be run in a standalone gemset with RVM, I have implemented it before, and now, I will make a guide to show you guys hwo to run multiple rails versions with phusion passenger and RVM.

Just give a example to you guys, I have project 'foo' run with rails 3.0.10 and project 'bar' run with rails 3.1.3 which is the latest version for rails 3, As of Phusion Passenger 3 you can run all components as Phusion Passenger.

The setup that we currently recommend is to combine Phusion Passenger for Nginx, with Phusion Passenger Standalone. All applications that are to use a different gemset can be served separately through Phusion Passenger Standalone and hook into the main web server via a setup load paths configuration.

To run project 'foo' under gemset 'foo', you need to do several simple configurations below:

First you need to add a .rvmrc file to your rails root directory, I think every one may use this, if you don'y use rvmrc, never mind, just create it by yourself with

$ rvm --rvmrc --create 1.9.3@foo

Then the .rvmrc file will be created, yeah, that's cool for the new functionanlity by RVM.

Create config/setup_load_paths.rb file in config directory, prefill with:

    if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm')
      begin
        rvm_path     = File.dirname(File.dirname(ENV['MY_RUBY_HOME']))
        rvm_lib_path = File.join(rvm_path, 'lib')
        $LOAD_PATH.unshift rvm_lib_path
        require 'rvm'
        RVM.gemset_use! 'foo'
      rescue LoadError
        # RVM is unavailable at this point.
        raise "RVM ruby lib is currently unavailable."
      end
    end

    # Pick the lines for your version of Bundler
    # If you're not using Bundler at all, remove all of them

    # Require Bundler 1.0 
    ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', File.dirname(__FILE__))
    require 'bundler/setup'

    # Require Bundler 0/9
    # if File.exist?(".bundle/environment.rb")
    #   require '.bundle/environment'
    # else
    #   require 'rubygems'
    #   require 'bundler'
    #   Bundler.setup
    # end

The same as project bar, the only difference is set a difference gemset.

After these two configuration steps, you can deploy your project to server now, if there is no gemset named 'foo' or 'bar on your server, you will got a error by running cap deploy:setup

ERROR: Gemset 'foo' does not exist, rvm gemset create 'foo' first.

Follow the error message, you need to create a gemset named 'foo' on your server first.

$ rvm use 1.9.3
$ rvm gemset create foo

Then the foo gemset will be created, you can deploy your project to your server now,

$ cap deploy:setup
$ cap deploy

'bundle install' will automatically install all the gems under 'foo' gemset and run server with the right rails version.

Here is the deploy script:

    $:.unshift(File.expand_path('./lib', ENV['rvm_path']))
    require "rvm/capistrano"
    ssh_options[:forward_agent] = true

    set :application, "foo"
    set :rvm_ruby_string, "1.9.3@#{application}"
    set :rvm_path, "/home/jerry/.rvm"
    set :rvm_bin_path, "/home/jerry/.rvm/bin"
    set :rvm_trust_rvmrcs_flag, 1

    set :scm, :git
    set :repository, "your_git_repo_url_here"
    set :branch, "master"

    set :deploy_to, "your_deploy_path_here/#{application}"
    set :user, "jerry"
    set :use_sudo, false
    server "your_server_domain_or_ip_here", :app, :web, :db, :primary => true
    set :deploy_via, :copy

    task :configure, :roles => :web do
      run "ln -s #{shared_path}/config/database.yml #{current_release}/config/database.yml"
      run "cd #{current_release}; bundle install --without development test"
    end

    task :trust_rvmrc, :roles => :web do
      run "rvm rvmrc trust #{current_release}"
    end

    after "deploy:update_code", :trust_rvmrc
    after 'deploy:update_code', :configure
    

Wish you happy with your deployment.

Posted at 13 Dec 2011

blog comments powered by Disqus