Как стать автором
Обновить

Поднимаем на одном сервере несколько Ruby on Rails проектов под разными версиями ruby (Nginx + Unicorn)

Время на прочтение4 мин
Количество просмотров17K
Здравствуйте, хабралюди!

Хочу поделиться с вами способом разворачивания нескольких приложений Ruby on Rails на одном сервере.
Поможет нам в этом RVM, Unicorn и Nginx.

Недавно заказчик попросил поставить Redmine к ним на сервер, на котором уже крутился проект на Ruby on Rails и использующий версию руби 1.9.2. А redmine работает максимум с ruby-1.8.7. Так как других проектов на сервер размещать не предполагалось, то там изначально поставили Nginx + mod_passenger. Как известно, используя mod_passenger на одном сервере не запустишь два приложения с разными версиями руби.

Для начала установим для каждого проекта свое окружение при помощи RVM.
Предполагается, что rvm у вас установлен, если нет, то устанавливаем.

Нам нужно две версии руби:

$ rvm install 1.9.2
$ rvm install 1.8.7


Для удобства создадим для каждого проекта свой набор гемов:

$ rvm use 1.9.2
$ rvm gemset create project

$ rvm use 1.8.7
$ rvm gemset create redmine


Соответственно получаем наборы 1.9.2@project и 1.8.7@redmine

Для того, чтобы rvm автоматически переключался на нужную версию руби и набор гемов делаем следующее:

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


Теперь в консоли при смене каталога проекта будет автоматически подключена нужная версия руби и набор гемов для проекта.

Нужно установить unicorn. Для проекта с версией рельсов от 3.0 это делается добавлением строки
gem 'unicorn'

в файл Gemfile в корне проекта и запуском

$ bundle install


В случае с редмайном, установить unicorn нужно так:

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


Создаем конфиг проекта для 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


Делаем конфиг для другого проекта по аналогии.

Теперь нам нужно запустить unicorn как демон, для каждого проекта свой:

$ 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


Осталось настроить nginx. Добавим в 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;
    }
}


Соответственно с каждого «виртуалхоста» делаем проксипасс на нужный поток, который использует соответствующий сокет юникорна.

server {
    listen 80;
    server_name project;

    location / {

        root /home/username/www/project/public;

        if (!-f $request_filename) {
            #делаем проксипасс на первый поток "project"
            proxy_pass http://project; 
            break;
        }
    }

}


и

server {
    listen 80;
    server_name redmine;

    location / {

        root /home/username/www/redmine/public;

        if (!-f $request_filename) {
            #делаем проксипасс на второй поток "redmine"
            proxy_pass http://redmine; 
            break;
        }
    }

}


Перезапускаем nginx. Готово.

Надеюсь кому-то пригодится и сбережет время.
Теги:
Хабы:
+21
Комментарии39

Публикации

Истории

Работа

Ruby on Rails
11 вакансий

Ближайшие события