使用Meteor服务器的NGINX代理到URL的proxy_pass

5
我已经配置了一个Meteor服务器并设置了nginx配置。路由可以正常工作,但是当配置动态子域名指向Web应用程序的特定部分时,在加载Meteor文件时浏览器会产生404错误。
我正在尝试将所有*.domain.com重定向到http://localhost:3000/booking/ 我的配置如下:
server {

        server_name *.domain.com;
        listen 80;

        location / {
            proxy_pass http://localhost:3000/booking/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade; #for websockets
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
         }

}

404错误发生在Meteor JS文件中。

enter image description here

如果我删除以上nginx子域配置并访问一个子域,它可以完美地工作,加载路由应用程序。我认为我缺少一些东西来正确加载应用程序。
只有当我代理到URL中的路由/booking时,才会出现此问题。

你的URL变成了http://localhost:3000/booking/380......js?meteor....,我想这完全是无效的吧?这就是为什么会出现404错误。它应该位于http://localhost:3000/3850....js - Tarun Lalwani
是的,根URL会发生变化,需要指向没有“booking”的根目录。我该怎么做? - Allreadyhome
@Allreadyhome,所以,如果你从proxy_pass中删除/booking/,整个事情就能正常工作了吗?那么什么没有正常工作——你实际想要做什么,以及你在做这件事时遇到了什么问题?! - cnst
@Allreadyhome,你试过我的设置了吗? - Jankapunkt
2个回答

0

我有一个类似的设置,我在几个子域名上配置了不同的Meteor应用程序,以及在域名根目录上的静态网站,所有这些都相互指向不同的端口。

以下是我的设置步骤。

文件夹结构、位置和代理传递

首先要考虑的是文件夹结构。根据您的子域名的VHost-root目录,有一个相对路径到您的子域名的应用程序文件夹。

想象一下以下设置:

/www (dir, usually under /var)
  /domain (dir)
    /websitexy (dir, a static website is deployed under this dir)
    /subdomain (dir)
      /books (dir, subdomain app is deployed under this dir)

对于这样的设置,我制作了我的nginx配置文件,将其指向子域中应用程序的位置:

location /books {

当我第一次启动我的应用程序时,我遇到了类似的问题。我发现一个事情,就是当我在私有ip/port组合上设置proxy_pass时,我的配置起作用:

proxy_pass http://172.x.x.x:3000;

这也涉及到在该条目上的端口号后删除路由名称(/books)。现在您的代理通过所有在子域中的路由。

关于路由的注意事项

请注意,这里可能会有关于路由的混淆。通过设置location属性,您设置了nginx级别的路由(服务器的目录结构),因此在代理传递中没有路由。

您的应用程序可能已定义了其自己的内部路由。很重要的是,您应用程序的内部路由器基于其应用程序ur根据接收所有请求。这就是为什么重要的原因是代理传递不包括端口号后的任何路径。

Websocket

我已阅读了一些有关nginx和websocket连接的文章。基本上,我的初始设置来自这篇文章,并且看起来像这篇文档文章

location /app {
    proxy_pass 172.x.x.x;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
}

我还不得不添加proxy_read_timeoutproxy_send_timeout,否则会出现websocket协议问题:

默认情况下,如果代理服务器在60秒内没有传输任何数据,则连接将关闭。可以使用proxy_read_timeout指令增加此超时时间。

因此,我还设置了超时值:

proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
proxy_set_header Connection "upgrade";

在这里阅读更多这里

总结我的设置如下(使用您的应用凭据):

location /books {
    proxy_pass http://172.x.x.x:3000;
    proxy_http_version 1.1;
    proxy_read_timeout 36000s;
    proxy_send_timeout 36000s;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
}

为了解决您的问题,您可以检查您的虚拟主机目录(即您的应用程序部署的目录,参见上面的文件夹结构),并相应地更改您的locationproxy_pass设置。

如果这不起作用,您可能需要添加一些更多的错误输出,例如连接尝试时日志的摘录。


0

解决这个问题有不同的方法。

1 - 如果出现404错误,请尝试使用没有预订URL的备选方案

server {

        server_name *.domain.com;
        listen 80;

        location / {
            proxy_pass http://localhost:3000/booking/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade; #for websockets
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            error_page 404 = @fallback;
         }

      location @fallback {
            proxy_pass http://localhost:3000/$request_uri;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade; #for websockets
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
      }

}

2 - 为js和css设置单独的块

server {

        server_name *.domain.com;
        listen 80;

        location / {
            proxy_pass http://localhost:3000/booking/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade; #for websockets
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
         }

      location ~ \.(js|css|font)$ {
            proxy_pass http://localhost:3000/$request_uri;
            proxy_http_version 1.1;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
      }

}

执行此操作会产生“proxy_pass在正则表达式给定的位置不能有URI部分”的错误。 - Allreadyhome
这成功地允许重新启动nginx服务器,但在项目无法找到Meteor JS的情况下仍存在相同的404问题。你可以通过访问bob.badgerbookings.com来查看这一点。而访问http://badgerbookings.com/则可以正常加载该项目。 - Allreadyhome
你可以尝试在这个配置中添加 proxy_intercept_errors on; 吗?我想我可能忘了它,并且它会直接将404发送给客户端。 - Tarun Lalwani
测试两种配置仍然出现相同的404错误。我想知道Meteor项目中是否需要设置某些内容? - Allreadyhome
让我们在聊天中继续这个讨论 - Tarun Lalwani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接