nginx和unicorn上的多个rails应用程序

时间:2013-01-04 15:09:20

标签: ruby-on-rails ubuntu nginx unicorn

我使用Screencast 335部署到VPS教程成功设置了rails网站。现在我想在新域上添加另一个rails应用程序,但我对所需的步骤感到困惑。

在上面的设置中,site-available或/etc/nginx/nginx.conf没有变化。唯一的配置是在我的apps配置目录中的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 个答案:

答案 0 :(得分:21)

在unicorn.rb中:

申请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;
}

答案 1 :(得分:4)

使用Nginx和Unicorn在一台主机上托管不同的应用程序非常容易。

通过定义每个应用程序的socket文件的不同名称,可以获得分离。当然,您应该在current/public的{​​{1}}部分指出正确的server目录。

最后一次触摸在nginx.conf文件中:在它的顶部,您应该使用应用程序的unicorn_init.sh目录的完整路径更改APP_ROOT

如果你的设置类似于RailsCast的设置,那么所有其他事情都由capistrano完成。

答案 2 :(得分:4)

我就自己在这里提出的问题回答了这个问题:

Multiple Rails 4 app using nginx + unicorn

但这是一个答案:

我正在使用 Ruby 2.0 Rails 4.0 。我想你已经安装了nginx和unicorn。那么,让我们开始吧!

在你的 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;
  }

现在你可以将Unicorn作为Deamon:

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 ,只需 / 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 root。