使用 nginx 映射 rails 个应用程序

Using nginx to map rails applications

我想使用 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, I only get the HTML content, no assets/js/css as the browser tries to get them from http://127.0.0.1/assets instead of http://127.0.0.1/app1/assets.

有办法解决这个问题吗?

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/ break;
   }
   if ($http_referer ~* /app2) {
     rewrite ^(.*)$ app2/ break;
   }
   if ($http_referer ~* /app3) {
     rewrite ^(.*)$ app3/ break;
   }    
}

这是一个很好的默认配置,可以实现您想要实现的目标:

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, where I link to this example nginx config,因为 Rails。