Rails 4 服务器/VueJS 开发服务器和子域的 Nginx 反向代理

Posted

技术标签:

【中文标题】Rails 4 服务器/VueJS 开发服务器和子域的 Nginx 反向代理【英文标题】:Nginx reverse proxies for Rails 4 server/VueJS dev server and subdomains 【发布时间】:2019-11-04 17:06:38 【问题描述】:

我使用带有老化前端的单片 Rails 4 应用程序。我的主要目标是:在 VueJS 中构建一个新的独立前端,并将 Rails 服务器作为 API 使用,而 nginx 会在它们之间架起一座桥梁。

在我的开发环境中设置原型一直是一项挑战。这就是我的立场:

当前应用使用通配符子域,因此我需要能够处理 XYZ.localhost URL,无论 XYZ 是什么。 Webpack 开发服务器位于 http://localhost:8080。我打算默认将代理调用反向到此服务器。 旧版 Rails 开发服务器位于 http://localhost:3000。我打算在此处反向以/api/ 开头的代理调用。它在大多数请求中都需要一个子域,因此 http://clumsypanda.localhost/api/candy 应该代理到 http://clumsypanda.localhost:3000/candy

我想我已经完成了前两个:当我访问 http://XYZ.localhost 时,nginx 为我提供了 VueJS 内容。不过,我在拨打http://XYZ.localhost/api/whatever 时遇到了 502 错误。具体来说,nginx 报告:

XYZ.localhost 无法解析(3:找不到主机),客户端:::1, 服务器:本地主机,请求:“POST /api/login HTTP/1.1”,主机: “XYZ.localhost”,引用者:“http://XYZ.localhost/”

这是我的 nginx 配置:

worker_processes  1;

events 
    worker_connections  1024;



http 
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /usr/local/var/log/nginx/access.log  main;
    error_log /usr/local/var/log/nginx/error.log;

    server 
        listen       80;
        listen       [::]:80;
        server_name  localhost;

        location ~ ^/api/ 
            proxy_pass http://$host:3000;
            proxy_set_header Real-IP $remote_addr;
            proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header NginX-Proxy true;
            proxy_redirect off;

            rewrite ^/api(.*)$ $1 break;
        

        location / 
            proxy_pass http://localhost:8080;
            proxy_set_header Real-IP $remote_addr;
            proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header NginX-Proxy true;
            proxy_redirect off;
        
    

    include servers/*;

我听说在 proxy_pass 子句中使用变量会调用一些奇怪的 DNS 解析器巫毒,所以我编辑了我的主机文件(OS X 上的/etc/hosts),看起来像这样:

127.0.0.1   localhost *.localhost
255.255.255.255 broadcasthost
::1             localhost

【问题讨论】:

【参考方案1】:

经过无数次实验,我最终得到了它。我需要捕获子域并将其应用于代理标头。此外,我需要一个上游块来强制 nginx 自己解析域。

upstream rails_api 
  server 127.0.0.1:3000;


server 
    listen       80;
    listen       [::]:80;
    server_name  ~^(?<subdomain>.+)\.localhost;
    location ~ ^/api/ 
        proxy_pass http://rails_api;
        proxy_set_header Real-IP       $remote_addr;
        proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header NginX-Proxy   true;
        proxy_set_header Host          $subdomain.localhost:3000;
        proxy_redirect off;

        rewrite ^/api(.*)$ $1 break;
    

    location / 
        proxy_pass http://localhost:8080;
        proxy_set_header Real-IP $remote_addr;
        proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header NginX-Proxy true;
        proxy_set_header Host        $host;
        proxy_redirect off;
    

【讨论】:

以上是关于Rails 4 服务器/VueJS 开发服务器和子域的 Nginx 反向代理的主要内容,如果未能解决你的问题,请参考以下文章

使用 Axios 将整个 HTML 项目加载到 VueJS 组件中

Rails - Vuejs 与 Foreman 一起运行

使用带有 VueJS2 的 Rails 5.1 API

Rails 4:为啥在生产中没有加载字体?

Rails 4 + Websocket-rails + Passenger + Nginx + 负载均衡器

在 Windows Apache MySQL 上的生产环境中部署 Rails 4