【问题标题】:Using nginx to map rails applications使用 nginx 映射 rails 应用程序
【发布时间】:2015-08-02 13:57:50
【问题描述】:

我想使用 nginx 将我的所有 Rails 应用程序映射到端口 80。

目前,我在端口 3000 3001 和 3002 上运行了 3 个 rails 应用程序,我想在端口 80 上使用 nginx 来映射它们:

http://127.0.0.1/app1 => 127.0.0.1:3000
http://127.0.0.1/app2 => 127.0.0.1:3001
http://127.0.0.1/app3 => 127.0.0.1:3002

这就是我所做的:

server {
    listen 80;
    location /app1/ {
        proxy_pass http://127.0.0.1:3000/;
    }

    location /app2/ {
        proxy_pass http://127.0.0.1:3001/;
    }

    location /app3/ {
        proxy_pass http://127.0.0.1:3002/;
    }
}

但是,当我尝试访问 http://127.0.0.1/app1 时,我只获得 HTML 内容,没有资产/js/css,因为浏览器尝试从 http://127.0.0.1/assets 而不是 http://127.0.0.1/app1/assets 获得它们。

有没有办法解决这个问题?

【问题讨论】:

    标签: ruby-on-rails nginx


    【解决方案1】:

    ActionController::Base.relative_url_root = "/app1" 添加到app1 的config/environment.rb 末尾(其他两个应用类似)。这将使 Rails 为 URL 添加适当的前缀。

    如果你不想弄乱 Rails 配置,你可能会强制 Nginx 遍历所有资产文件夹,直到找到它需要的文件夹,如果我没记错的话,它可以像这样存档:

    location /assets/ {
      try_files /app1/$uri /app2/$uri /app3/$uri;
    }
    

    请注意,不同应用的资产必须具有不同的文件名。如果您在任何地方都使用资产管道,情况已经如此,因为它会散列文件名。

    UPD

    您也可以尝试基于“Referer”的路由:

    location /assets/ {
       if ($http_referer ~* /app1) {
         rewrite ^(.*)$ app1/$1 break;
       }
       if ($http_referer ~* /app2) {
         rewrite ^(.*)$ app2/$1 break;
       }
       if ($http_referer ~* /app3) {
         rewrite ^(.*)$ app3/$1 break;
       }    
    }
    

    【讨论】:

    • 谢谢,它可以工作,但有没有办法在不接触 Rails 应用程序的情况下实现这一点?如果我想托管一个无法修改的网络应用程序?
    • 不改变 Rails 配置是无法实现的。如果出现问题,只需更改生产配置。
    • 嗯,我可以看到两种方法可以实现“有点”:将资产混合在 common /assets 文件夹中,或者通过查看“Referer”标头使用 nginx 重定向。将使用建议的解决方法更新我的答案。
    • try_files 在 3 个不同的目录中是反模式,使用 config.assets.prefix 并通过 Nginx 位置前缀拦截它
    • location 上下文中使用多个ifs 是个坏主意,因为它已经documented several 次。这一系列if 块应该用try_files 重写。
    【解决方案2】:

    这是您想要实现的一个很好的默认配置:

    server {
        listen 80;
        location /app1/ {
            root /srv/rails/app1/public;
            try_files $uri $uri/index.html $uri.html @app1_forward;
        }
    
        location @app1_forward {
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header Host $http_host;
          proxy_redirect off;
          proxy_pass http://app1_backend;
        }
    
        location /app2/ {
            root /srv/rails/app2/public;
            try_files $uri $uri/index.html $uri.html @app2_forward;
        }
    
        location @app2_forward {
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header Host $http_host;
          proxy_redirect off;
          proxy_pass http://app2_backend;
        }
    
        location /app3/ {
            root /srv/rails/app3/public;
            try_files $uri $uri/index.html $uri.html @app3_forward;
        }
    
        location @app3_forward {
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header Host $http_host;
          proxy_redirect off;
          proxy_pass http://app3_backend;
        }
    }
    
    upstream app1_backend {
        server 127.0.0.1:3000    fail_timeout=0;
    }
    
    upstream app2_backend {
        server 127.0.0.1:3001    fail_timeout=0;
    }
    
    upstream app3_backend {
        server 127.0.0.1:3002    fail_timeout=0;
    }
    

    还要检查this article,我链接到this example nginx config,用于Rails。

    【讨论】:

    • 这不是完整的例子,如果没有将 Rails 资产目录指向 app1、app2、app3 中的任何一个,它将无法工作
    • 它应该可以工作,但它会效率低下。这些链接将指向一个完整的配置文件。
    • 我不明白您如何为 app1 加载合适的 /assets/all.js
    • @Anatoly 检查this
    • 我知道如何让 Nginx 使用单个 server 块为多个后端应用程序提供服务。我在问什么,您如何在没有额外的 Rails 配置 config.assets.prefix 的情况下区分 3 个不同的应用程序(3 个不同的根指令)之间的 all.js?该指令旨在解决该问题。
    猜你喜欢
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    相关资源
    最近更新 更多