Несколько рельсовых приложений на nginx и единороге

Я успешно настроил сайт rails с помощью развертывания Screencast 335 в руководстве по VPS. Теперь я хочу добавить другое приложение rails на новый домен, но я не совсем понимаю, какие шаги нужно предпринять.

В приведенной выше настройке нет изменений для сайтов, доступных или /etc/nginx/nginx.conf. Единственная конфигурация находится в unicorn.rb, unicorn_init.sh и nginx.conf в моем каталоге конфигурации приложений. Файл nginx.conf выглядит так:

upstream unicorn {
  server unix:/tmp/unicorn.my_app.sock fail_timeout=0;
}
server {
  listen 80 default deferred;
  # server_name my_app.com.au www.my_app.com.au;
  root /var/www/my_app/current/public;
  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }
  try_files $uri/index.html $uri @unicorn;
  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://unicorn;
  }
  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
}

В моем рецепте Capistrano у меня есть эта строка

sudo "ln -nfs #{current_path}/config/nginx.conf /etc/nginx/sites-enabled/#{application}"

Является ли добавление второго домена просто вопросом удаления отложенного по умолчанию после прослушивания и отмены комментариев раздела server_name, а затем повторения этого файла конфигурации с другим именем восходящего сокета и именем сервера для второго приложения? Будет ли это работать или мне нужно перенести этот файл на сайты, доступные и создать символическую ссылку на сайты с поддержкой?

3 ответа

Решение

Размещать разные приложения на одном хосте с Nginx и Unicorn действительно легко.

Разделение вы можете получить, определив разные имена socket файлы каждого приложения. Конечно, вы должны указать правильный current/public каталоги в server раздел nginx.conf,

Последний штрих в unicorn_init.sh файл: поверх него вы должны изменить APP_ROOT с полным путем к current/public каталог вашего приложения.

Если ваша установка похожа на настройку RailsCast, все остальное делает capistrano.

В единороге

Приложение 1:

root = "/var/www/application_1/current"
working_directory root
pid "#{root}/tmp/pids/unicorn-app1.pid"
listen "/tmp/unicorn.app1.sock"

Приложение 2:

root = "/var/www/application_2/current"
working_directory root
pid "#{root}/tmp/pids/unicorn-app2.pid"
listen "/tmp/unicorn.app2.sock"

В nginx.conf:

Приложение 1:

upstream app1_server {
  server unix:/tmp/unicorn.app1.sock fail_timeout=0;
}

server {
  listen 80;
  server_name my_app_1.com www.my_app_1.com;
  root /var/www/app1/current/public;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @app1_server;
  location @app1_server {
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_redirect off;
  proxy_pass http://app1_server;
 }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
}

Приложение 2:

upstream app2_server {
  # point to app2 sock
  server unix:/tmp/unicorn.app2.sock fail_timeout=0;
}

server {
  listen 80;
  server_name my_app_2.com www.my_app_2.com;
  root /var/www/app2/current/public;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @app2_server;
  location @app2_server {
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_redirect off;
  proxy_pass http://app2_server;
 }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
}

Я ответил на вопрос, который сделал сам здесь:

Приложение Multiple Rails 4, использующее nginx + единорог

Но вот ответ:

Я использую Ruby 2.0 и Rails 4.0. Я полагаю, у вас уже установлены nginx и единорог. Итак, начнем!

В вашем файле nginx.conf мы собираемся сделать так, чтобы nginx указывал на сокет единорога:

upstream unicorn_socket_for_myapp {
  server unix:/home/coffeencoke/apps/myapp/current/tmp/sockets/unicorn.sock fail_timeout=0;
}

Затем, когда ваш сервер прослушивает порт 80, добавьте блок местоположения, указывающий на подкаталог, в котором находится ваше приложение rails (этот код должен находиться внутри блока сервера):

location /myapp/ {
    try_files $uri @unicorn_proxy;
  }

  location @unicorn_proxy {
    proxy_pass http://unix:/home/coffeencoke/apps/myapp/current/tmp/sockets/unicorn.sock;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_set_header X-Forwarded-Proto $scheme;
  }

Теперь вы можете просто Единорог как Деймон:

sudo unicorn_rails -c config/unicorn.rb -D

Последнее, что нужно сделать, и то, что я выкопал больше всего, это добавить область для вашего файла маршрутов rails, например так:

MyApp::Application.routes.draw do
  scope '/myapp' do
    root :to => 'welcome#home'

    # other routes are always inside this block
    # ...
  end
end

Таким образом, ваше приложение будет отображать ссылку / myapp / welcome, intead of just / welcome

Но есть еще лучший способ

Что ж, вышесказанное будет работать на производственном сервере, но как насчет разработки? Собираетесь ли вы нормально развиваться, тогда при развертывании вы меняете конфигурацию rails? Для каждого приложения? Это не нужно.

Итак, вам нужно создать новый модуль, который мы собираемся разместить на lib/route_scoper.rb:

require 'rails/application'

module RouteScoper
  def self.root
    Rails.application.config.root_directory
  rescue NameError
    '/'
  end
end

После этого в вашем routes.rb сделай это:

require_relative '../lib/route_scoper'

MyApp::Application.routes.draw do
  scope RouteScoper.root do
    root :to => 'welcome#home'

    # other routes are always inside this block
    # ...
  end
end

Что мы делаем, так это проверяем, указан ли корневой каталог, и если да, то используем его, в противном случае получаем "/". Теперь нам просто нужно указать корневой каталог в config/enviroments/production.rb:

MyApp::Application.configure do
  # Contains configurations for the production environment
  # ...

  # Serve the application at /myapp
  config.root_directory = '/myapp'
end

В config/enviroments/development.rb я не указываю каталог config.root_directory. Таким образом, он использует нормальный корень URL.

Другие вопросы по тегам