Nginx 能否将本地的多个端口转发到同一端口的不同目录

2021-02-13 02:23:25 +08:00
 nellxzy

玩树莓派遇到的问题,自己查了很久资料没搞定,求求论坛的各位大神指点!

背景

设备是树莓派,用了花生壳的内网穿透,免费版只提供两个端口,SSH 用掉一个 22 端口,现在只剩一个端口了。

我有如下服务:

受到 Aria-NG 的启发,所以我在想能不能用 Nginx 实现如下转发:

我查到 Nginx 的默认端口是 80,如果上面可以实现的话,或许就可以只用一个 80 端口来使用多个服务。(应该是可以的,我之前试了 80 端口,用 外网域名:外网端口 /aria-ng 可以访问 Aria-NG,但是因为 Aria2 的 RPC 在 6800,所以只有 Aria-NG 的界面,没法实际使用。)

目前的失败尝试

/etc/nginx/nginx.conf中,进行如下修改:

html {
	......
    
    server {
        listen 80;
        server_name localhost;

        # Jupyter Notebook
        location /jupyter {
            proxy_pass http://localhost:8888;
            ......
        }

        # Aria2 JSONRPC
        location /jsonrpc {
            proxy_pass http://localhost:6800/jsonrpc;
            ......
        }
        
        # XXX
        location /xxx {
        	proxy_pass http://localhost:5299;
            ......
    }
}

重启 nginx 服务后,在树莓派上访问localhost/jupyter,错误 404 。局域网访问或外网访问自然也失败了。

查到的资料基本上都是一个端口或域名转发到另一个端口或域名的,基本没有我这里的多个端口转发到同一端口的不同目录。还有一些用到了 stream 模块,但也是局域网内的端口对端口。只有这个帖子比较像: https://www.imooc.com/wenda/detail/510191 ,但是没有详细答案。

当然,这个问题不用花生壳就能解决了,但还是好奇,上面提的方案有没有实现的可能性?

5026 次点击
所在节点    NGINX
29 条回复
liuhan907
2021-02-13 14:26:42 +08:00
此功能还是建议使用 traefik 。
chairuosen
2021-02-13 14:48:19 +08:00
用域名呗。。。。内网域名
IvanLi127
2021-02-13 15:47:13 +08:00
把 server_name 这行去掉
dorothyREN
2021-02-13 19:00:28 +08:00
答案是可以
spolarbear
2021-02-13 19:49:56 +08:00
server {
listen 5000;
server_name 192.168.0.173;

location /geoserver {
proxy_pass http://localhost:8080;
#proxy_redirect http://localhost http://localhost:8080;
proxy_set_header Host $host:5000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

自用这个可行,访问 192.168.0.173:5000/geoserver 的话,会转发到 8080 端口。
Judoon
2021-02-13 22:38:32 +08:00
据我之前使用,jupyter 是不行的,前端加载的样式等静态资源链接的路径不会被改写(即无法修改为自定义的 context path )

如果我哪里漏看了文档,或者楼主搞出来了可以教教我

除了 jupyter,列举的其他几个目测都是可以用 nginx 实现的。当然,最好的方式是基于域名( server_name )分发
nellxzy
2021-02-14 01:48:48 +08:00
感谢大家的回复,现在有了一个初步的方案,能转发 jupyter,aria2-jsonrpc 和 aria-ng 。

配置方法:
首先, [/etc/nginx/nginx.conf] 作如下修改:
```
http {
......

server {
listen 4000;
server_name localhost;

# Jupyter Notebook
location /jupyter/ {
proxy_pass http://localhost:8888;
proxy_set_header Host $host:$server_port;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# websocket headers
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Scheme $scheme;

proxy_read_timeout 120s;
proxy_next_upstream error;
}

# Aria2 JSONRPC
location /jsonrpc {
proxy_pass http://localhost:6800;
}

# Aria-NG
location /aria-ng/ {
proxy_pass http://localhost:80;
}
}
}
```

其次, [~/.jupyter/jupyter_notebook_config.py] 追加如下部分:
```
# 将 Jupyter 的工作路径改成 localhost:8888/jupyter/
# 参考 https://segmentfault.com/a/1190000016627630
c.NotebookApp.base_url = '/jupyter/'

# 允许任何源访问服务,修复用 nginx 反向代理访问时 kernel 与 terminal 无法加载的问题
# 参考 https://juejin.cn/post/6844903877481857037
c.NotebookApp.allow_origin = '*'
```

一些记录:
1. 端口之所以选 4000,是因为设置成 80 时有问题,所以就另找了一个空闲的端口。
2. location 和 proxy_pass 的写法,主要参考了这一篇: https://xuexb.github.io/learn-nginx/example/proxy_pass.html
3. jupyter 本来是工作在 [localhost:8888/] 下的,我想让它工作在 [localhost:4000/jupyter/] 下。尝试了 location 和 proxy_pass 的各种写法,以及 rewrite,没成功。某些配置下,有一种典型的现象是,访问[localhost:4000/jupyter/]时,地址跳转到[localhost:4000/tree?](对应本体的[localhost:8888/tree?]),而不是[localhost:4000/jupyter/tree?],但手动输入后者,也没法正常显示。所以退而求其次,让 jupyter 本体工作在[localhost:8888/jupyter/]下。
4. 接下来又出现了一个问题,打开 jupyter 后,虽然文件管理界面没问题,但是 kernel 和 terminal 无法加载。所以又加入了允许所有源访问服务,解决了这个问题。

概括一下:
能够工作在端口下一个目录的服务,比如
- localhost:8888/jupyter/
- localhost:6800/jsonrpc
- localhost:80/aria-ng/
可以转发。但是直接工作在端口下的服务,比如
- localhost:5299/
没弄出来。树莓派能安装的 Nginx 版本只有 1.14.2,不知道跟版本有没有关系。
nellxzy
2021-02-14 01:51:32 +08:00
@Judoon jupyter 可以了
rekulas
2021-02-14 22:09:06 +08:00
路径转发并不总是可行,因为被转发的程序也必须支持跟你定义的根路径一样才可以,我觉得更完美的方案是域名控制,即使一个端口也可以转发任意多个服务(没有用花生壳所以不太清楚能不能支持域名)
我和我的朋友从不会有这些问题,因为是公网 IP,想开哪个端口开哪个。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/753126

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX