我正在尝试运行多个 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/">
答案2
所以,这其实是 NodeJS 应用程序本身的问题,而不是环境设置的问题。似乎应用程序试图耍小聪明,获取应用程序的根目录,但却不知道它正在被代理(或类似的东西)。
当我用一个干净的基本应用程序尝试它时,它按预期工作并且相对路径有效。
答案3
更新
看起来您的 nginx 代理正在运行,问题在于您的应用程序使用指向主域的硬编码链接。这似乎是应用程序施加的限制,nginx 无法真正帮助您解决这个问题,因为它无法知道您何时访问文件,例如/css/style.css
是否应该将其重定向到/NodeJsApplication1
或/NodeJsApplication2
。
旧答案
您不能将两个不同的应用程序绑定到同一系统上的同一端口。您应该做的是将它们绑定到不同的端口,然后在 nginx 配置中传递到特定的应用程序端口,如下所示(这假设您使用3000
app1 的端口和3001
app2 的端口):
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');
此值“信任代理”默认值为禁用。