在单个端口上托管多个 Nodejs 应用程序

在单个端口上托管多个 Nodejs 应用程序

我正在尝试运行多个 nodejs 应用程序(使用 express 框架),所有应用程序都在同一个外部端口(80)上提供服务,但每个应用程序都在一个子目录下。

例如我想要...

NodeJsApplication1 将在http://www.mydomain.com/NodeJsApplication1

NodeJsApplication2 将于http://www.mydomain.com/NodeJsApplication2

ETC。

我尝试使用 Nginx 作为代理,其配置与以下类似。

server {
    listen       80;
    server_name  www.mydomain.com;

    location / {
        root   /var/www/html;
        index  index.html index.htm;
    }

    location /NodeJsApplication1/ {
        proxy_pass http://0.0.0.0:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        rewrite /NodeJsApplication1/(.*) /$1 break;
    }

    location /NodeJsApplication2/ {
        proxy_pass http://0.0.0.0:3001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        rewrite /NodeJsApplication2/(.*) /$1 break;
    }
}

这种方法可以访问页面,但会破坏返回页面上的所有相关 URL。所有脚本和 CSS 等都指向根目录(例如 www.mydomain.com/styles/main.css)。

我知道我可以使用多个子域名,但不想走这条路。我更喜欢使用子文件夹代理,这样一切都由软件处理,我不需要为每个应用程序设置任何 DNS 记录。

这可能吗?

更新

在应用程序本身中,所有链接都使用相对路径。例如:

<link href="styles/main.css" />
<script src="scripts/app.js" />

但是在呈现时,浏览器会将它们视为“ www.mydomain.com/styles/main.css”而不是“ www.mydomain.com/NodeJsApplication1/styles/main.css”。

更新 2 我知道该问题的三种可能的(非理想的)解决方案。

  • 第一个是修改 NodeJS 应用程序以指定完整的 URL但这要求应用程序知道 nginx 配置的子目录,并且会破坏向另一个环境的可移植性。
  • 第二种是使用子域名。我知道这是可行的,每个应用程序都可以设置为NodeJsApplication1.mydomain.com,所有链接都会按预期运行。我遇到的问题是它需要为每个应用程序设置一个 DNS 记录。我想要一些几乎可以自动完成而无需大量手动工作的东西。(通配符记录不合适,因为域用于其他目的)。
  • 使用<base>标签指定应用程序的根目录。这又存在要求更改应用程序而不是环境的问题。

答案1

我在同一个域中拥有多个 MEAN 应用程序时遇到了类似的问题。我想要子目录,而不是为每个应用程序创建一个新的子域。除了在 Nginx 配置中添加重写之外:

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

您还需要<base>在索引的头部设置标签:

<base href="/app1/">

https://www.digitalocean.com/community/questions/how-to-run-multiple-node-application-with-nginx-same-droplet-same-domain

答案2

所以,这其实是 NodeJS 应用程序本身的问题,而不是环境设置的问题。似乎应用程序试图耍小聪明,获取应用程序的根目录,但却不知道它正在被代理(或类似的东西)。

当我用一个干净的基本应用程序尝试它时,它按预期工作并且相对路径有效。

答案3

更新

看起来您的 nginx 代理正在运行,问题在于您的应用程序使用指向主域的硬编码链接。这似乎是应用程序施加的限制,nginx 无法真正帮助您解决这个问题,因为它无法知道您何时访问文件,例如/css/style.css是否应该将其重定向到/NodeJsApplication1/NodeJsApplication2

旧答案

您不能将两个不同的应用程序绑定到同一系统上的同一端口。您应该做的是将它们绑定到不同的端口,然后在 nginx 配置中传递到特定的应用程序端口,如下所示(这假设您使用3000app1 的端口和3001app2 的端口):

location /NodeJsApplication1/ {
    proxy_pass http://0.0.0.0:3000;
    ...
}


location /NodeJsApplication2/ {
    proxy_pass http://0.0.0.0:3001;
    ...
}

答案4

关于问题,css、js、images文件丢失,你可以这样做

如果你使用 express 框架,你需要添加这行代码

app.enable('trust proxy');

此值“信任代理”默认值为禁用。

相关内容