We raise several Ruby on Rails projects on the same server under different versions of ruby ​​(Nginx + Unicorn)

    Hello habra

    I want to share with you how to deploy multiple Ruby on Rails applications on the same server.
    It will help us in this RVM, Unicorn and Nginx.

    Recently, the customer asked to put Redmine on them on a server on which the Ruby on Rails project was already running and using the Rub version 1.9.2. And redmine works with a maximum of ruby-1.8.7. Since it was not intended to place other projects on the server, Nginx + mod_passenger was originally installed there. As you know, using mod_passenger on the same server you won’t run two applications with different versions of Ruby.

    First, we’ll set up our environment for each project using RVM.
    It is assumed that rvm is installed, if not, then install .

    We need two versions of the cut:

    $ rvm install 1.9.2
    $ rvm install 1.8.7
    


    For convenience, we will create for each project our own set of gems:

    $ rvm use 1.9.2
    $ rvm gemset create project
    $ rvm use 1.8.7
    $ rvm gemset create redmine
    


    Accordingly, we get sets 1.9.2@project and 1.8.7@redmine

    In order for rvm to automatically switch to the desired version of the cut and set of gems, do the following:

    $ echo "rvm use 1.9.2@project" > /home/username/www/project/.rvmrc 
    $ echo "rvm use 1.8.7@redmine" > /home/username/www/redmine/.rvmrc 
    


    Now in the console, when changing the project directory, the correct version of the ruby ​​and a set of gems for the project will be automatically connected.

    You need to install unicorn. For a project with rails version from 3.0, this is done by adding a line
    gem 'unicorn'
    

    to the gemfile in the root of the project and running

    $ bundle install
    


    In the case of redmine, you need to install unicorn like this:

    $ cd /home/username/www/redmine
    $ gem install unicorn
    


    Create a project config for unicorn (/home/username/www/redmine/config/unicorn.rb):

    worker_processes 2
    working_directory "/home/username/www/redmine/"
    preload_app true
    timeout 30
    listen "/home/username/www/redmine/tmp/sockets/unicorn.sock", :backlog => 64
    pid "/home/username/www/redmine/tmp/pids/unicorn.pid"
    stderr_path "/home/username/www/redmine/log/unicorn.stderr.log"
    stdout_path "/home/username/www/redmine/log/unicorn.stdout.log"
    before_fork do |server, worker|
        defined?(ActiveRecord::Base) and
            ActiveRecord::Base.connection.disconnect!
    end
    after_fork do |server, worker|
        defined?(ActiveRecord::Base) and
            ActiveRecord::Base.establish_connection
    end
    


    We make a config for another project by analogy.

    Now we need to run unicorn as a daemon, for each project our own:

    $ cd /home/username/www/redmine
    $ unicorn_rails -c config/unicorn.rb -E production -D
    $ cd /home/username/www/project
    $ unicorn_rails -c config/unicorn.rb -E production -D
    


    It remains to configure nginx. Add two stream handlers (one for each project) to nginx.conf:

    ...
    http {
        ...
        upstream project {
            # путь должен совпадать с тем, что в конфиге unicorn.rb
            server unix:/home/username/www/project/tmp/sockets/unicorn.sock;
        }
        upstream redmine {
            server unix:/home/username/www/redmine/tmp/sockets/unicorn.sock;
        }
    }
    


    Accordingly, from each "virtual host" we make a proxy pass to the desired stream, which uses the corresponding unicorn socket.

    server {
        listen 80;
        server_name project;
        location / {
            root /home/username/www/project/public;
            if (!-f $request_filename) {
                #делаем проксипасс на первый поток "project"
                proxy_pass http://project; 
                break;
            }
        }
    }
    


    and

    server {
        listen 80;
        server_name redmine;
        location / {
            root /home/username/www/redmine/public;
            if (!-f $request_filename) {
                #делаем проксипасс на второй поток "redmine"
                proxy_pass http://redmine; 
                break;
            }
        }
    }
    


    Restart nginx. Done.

    I hope someone comes in handy and saves time.

    Also popular now: