Есть задача, даже две. Первая - разобраться с настройкой nginx для отдачи rails-статики и балансировки двух (трёх, сколько нужно), mongrel-ов. Вторая - всё то же самое, но без mongrel, а с использованием passenger и, главное, через capistrano.
Nginx + mongrels
Первую задачу я реализовывал локально, на своей уютненькой убунте и всё решилось сравнительно мирно.
Убрал из дефолтной конфигурации все директивы server и upstream, оставил только директивы include - так гибче, если что.
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;Добавил в отдельный файл конфигурацию апстрима на двух монгрелах (важен был сам принцип, а не количество) и сервер:
upstream mongrel { # <-- имя upstream-а для ссылок на него
server localhost:3000; # Первый mongrel
server localhost:3001; # Второй mongrel
# <-- добавить mongrel-ы по вкусу
}
server {
listen 8084; # <-- номер порта
server_name ~^(?<subdomain>[-\w]+)\.lvh\.me$; # <-- Запоминаем subdomain
access_log off;
location / {
proxy_pass http://mongrel;
proxy_set_header Host $subdomain.lvh.me:8084; # <-- Передаём subdomain и port
}
location ~ ^/(image|stylesheet|javascript)s {
root /home/user_name/devel/rails/project_name/public;
}
}Отдельный пункт в первой задаче был - сохранить для использования в рельсовских контроллерах субдомен, пришедший в запросе. Что и было реализовано при помощи server_name с регулярным выражением и proxy_set_header с использованием пришедшего из регэкспа поля $subdomain. Без передачи параметра Host в запросе к приложению приходил параметр “mongrel” с никаким субдоменом, а без передачи порта возникали проблемы с открытием следующих страниц (редиректы, ссылки и т.п.)
Теперь заходим на organization_name.lvh.me:8084 и в приложение приходят запросы с указанным субдоменом и разбрасываются между монгрелами. Как-то так.
Capistrano, а потом passenger
На самом деле, мне просто хотелось лёгкого деплоя. И поэтому я решил что на другую машину я буду деплоить при помощи capistrano. А passenger всплыл уже потом.
Начинаем, как водится, с нуля:
$ cd /home/user_name/devel/rails/project_name
$ capify .
$ emacs -nw config/deploy.rb # <-- Вместо emacs используйте Ваш любимый редактор ;)Полученный Capfile оставляем в покое, а вот с config/deploy.rb пришлось потанцевать, по целому ряду причин. Во-первых, мне категорически не хотелось использовать sudo при деплое, во-вторых, мне не хотелось вводить пароли при каждом деплое, в третьих, на удалённой машинке rvm был установлен из-под root-а.
Итак, берём deploy.rb и внимательно на него смотрим.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | |
Примерно так стал выглядеть deploy.rb на моей машинке (если комментарии не считать). В процессе мне пришлось разбираться, как настроить ssh-forwarding, как запускать на удалённой машине ssh-agent и как запускать passenger в standalone режиме и что man-ы и официальная документация are the developer’s best friends.
И всё было почти хорошо. И деплой проходил, не заканчиваясь сообщением, что какая-то команда не прошла, но вот рестарт passenger-а не происходил. Вот если бы passenger-а можно было бы запускать с командной строки, указывая, в каком каталоге будет производиться запуск, тогда бы, возможно, следующую часть можно было бы и опустить. А так мне пришлось устанавливать passenger в конкретном gemset-е, в нём же запускать установку nginx-модуля для passenger и настраивать nginx уже на работу с /home/user_name/deploy_path/public.
$ sudo rvm 1.9.2@project gem install passenger
$ sudo rvm 1.9.2@project passenger-install-nginx-module
$ sudo rvm 1.9.2@project passenger-config --root # <-- Отсюда возьмём путь к passenger-у
$ sudo vi /opt/nginx/conf/nginx.conf # <-- Да, иногда я пользуюсь vi. Особенно на удалённых машинах ;)Дальше - правки, внесенные в /opt/nginx/conf/nginx.conf
http {
# Сюда пишем то, что выдала команда passenger-config --root
passenger_root /usr/local/rvm/gems/ruby-1.9.2-p290@crm/gems/passenger-3.0.9;
# Эту строчку выставляет passenger-install-nginx-module (а откуда ещё я мог её взять?)
passenger_ruby /usr/local/rvm/wrappers/ruby-1.9.2-p290@crm/ruby;
...
# А вот этот кусочек я написал, глядя в руководство
server {
listen 80;
server_name _;
root /home/user_name/deploy_path/current/public;
passenger_enabled on;
}
...
}Перезапускаем nginx и идём пить кефир.