【问题标题】:multiple rails apps on nginx and unicornnginx 和 unicorn 上的多个 Rails 应用程序
【发布时间】:2012-12-19 01:00:22
【问题描述】:

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

在上述设置中,sites-available 或 /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 部分后删除默认延迟,然后为第二个应用程序使用不同的上游套接字名称和服务器名称重复此配置文件吗?这会起作用吗,还是我需要将此文件传输到可用站点并创建指向已启用站点的符号链接?

【问题讨论】:

    标签: ruby-on-rails ubuntu nginx unicorn


    【解决方案1】:

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

    您可以通过定义每个应用程序的socket 文件的不同名称来获得分离。当然,您应该在nginx.confserver 部分中指向正确的current/public 目录。

    最后一点是在unicorn_init.sh 文件中:在它的顶部,您应该将APP_ROOT 更改为应用程序的current/public 目录的完整路径。

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 您好!我使用与您相同的设置,并且坚持正确设置独角兽。您能否提供要点或其他内容,您的 deploy.rb 文件?你也在使用 RVM 吗?您是如何解决部署时的“包装器”部分的?
      • 无法编辑它,因为只有一个字符不同,但我认为在 App2 nginx.conf 中你应该引用 app2.sock 文件而不是 app1
      • 每个 niginx.conf 文件中的端口号不应该是 uniq 吗?
      • unicorn shell 脚本,init.d 中的那个呢?在我的设置中,它有一个硬编码的 APP_ROOT,它指向第一个应用程序。我需要为第二个应用创建另一个 shell 脚本吗?
      【解决方案3】:

      我在这里提出的一个问题上回答了这个问题:

      Multiple Rails 4 app using nginx + unicorn

      但这里有一个答案:

      我正在使用 Ruby 2.0Rails 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 的情况下,添加一个 location 块,指向您的 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,而不仅仅是 /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 根。

      【讨论】:

      • 聪明,我喜欢你的方法:-)
      • 感谢您的示例,是否可以创建有关的短视频教程?
      猜你喜欢
      • 1970-01-01
      • 2013-08-10
      • 2014-11-08
      • 1970-01-01
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 2015-08-15
      • 1970-01-01
      相关资源
      最近更新 更多