V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
AndreasG
V2EX  ›  NGINX

我有一个端口转发问题,求大佬们协助

  •  
  •   AndreasG · 17 小时 8 分钟前 · 1447 次点击

    我现在有三个容器开着,路由器开放了三个端口, 我想能不能开放一个端口用拼接 url 方式转发到不同的内网服务下,

    server {  
        listen 10086 ssl;  
        server_name abc.com;
            location / {  
            proxy_pass http://192.168.0.100:10086;
            proxy_set_header Host $host;  
            proxy_set_header X-Real-IP $remote_addr;  
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
            proxy_set_header X-Forwarded-Proto $scheme;
            }
    
    
            location /book {  
            proxy_pass http://192.168.0.100:10010;
            proxy_set_header Host $host;  
            proxy_set_header X-Real-IP $remote_addr;  
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
            proxy_set_header X-Forwarded-Proto $scheme;
            }
        }
    

    类似这样配置了 nginx 之后 直接访问 abc.com:10086 端口访问全部没问题 但是转发的第二个端口

    abc.com:10086/book
    

    并不能成功转发到 192.168.0.100:10010 浏览器调试发现使用 abc.com:10086/book 发出的请求中 css js 之类的都是

    abc.com:10086/static/?.css
    abc.com:10086/static/?.js
    

    而并没有到

    abc.com:10086/book/static/?.css
    abc.com:10086/book/static/?.js
    

    状态都是 404 了 问了一下 gpt 说是需要找到真实的静态资源地址,这个容器的话怎么搞呢?还是说我的 nginx 需要配置其他配置项才可以呢,求大佬们帮助

    第 1 条附言  ·  12 小时 0 分钟前

    多谢各位大佬解答,目前因为是前后端资源都不能很好的子u给,(都是docker容器)看了一下大佬们的解答,受用无穷

    最后我的解决方案

    1. 增加配置 *.name.com 的泛域名证书
    2. 在阿里云域名解析里配置了多个二级域名解析到同一个地址
    3. nginx 中配置使用了同端口不同域名的方式绕过了这个问题
    4. 最后贴上我的nginx配置部分,有需要可以参考,有不合理的也请各位大佬指出
    5. 非常感谢各位的协助,我已经实现了一个端口多个服务的需求
      server {  
       listen 3000 ssl;  
       server_name name.com www.name.com;  
       location / {  
           proxy_pass http://192.168.0.100:10086;  
           proxy_set_header Host $host;  
           proxy_set_header X-Real-IP $remote_addr;  
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
           proxy_set_header X-Forwarded-Proto $scheme;  
       }  
     
    }  
    server {  
       listen 3000 ssl;  
       server_name book.name.com www.book.name.com;  
           location / {  
           client_max_body_size 10M;  
           proxy_pass http://192.168.0.100:10010;  
           proxy_set_header Host $host;  
           proxy_set_header X-Real-IP $remote_addr;  
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
           proxy_set_header X-Forwarded-Proto $scheme;  
       }  
    }
    
    27 条回复    2025-01-09 20:01:20 +08:00
    ssiitotoo
        1
    ssiitotoo  
       16 小时 58 分钟前
    要实现所有静态都走 book 你需要更改静态入口文件的路劲添加 book 要不然 默认都是请求/
    doveyoung
        2
    doveyoung  
       16 小时 54 分钟前
    如果你的 192.168.0.100:10010 能识别 192.168.0.100:10010/book 这个路径,可以试试修改 nginx 的 proxy_pass 配置
    proxy_pass http://192.168.0.100:10010 ; --> proxy_pass http://192.168.0.100:10010/book ;
    如果你后端真正的服务识别不了 /book 这个路径,你可以在 nginx 额外加 server 配置 book.abc.com proxy_pass 到 192.168.0.100:10010

    我看你的 /book 还加了 proxy_set_header ,这样会让你后端真正的服务接收到 {host: abc.com} ,不知道这符不符合你的期望
    jupiterISme
        3
    jupiterISme  
       16 小时 49 分钟前
    location /book {
    proxy_pass http://192.168.0.100:10010/book;
    ...
    }
    试试这个
    sagaxu
        4
    sagaxu  
       16 小时 35 分钟前
    你的网站支持部署到非根路径吗?网站不支持也是白搭。
    zizon
        5
    zizon  
       15 小时 35 分钟前
    说明你
    http://192.168.0.100:10010 host 的页面的资源路径写的就是 static/?.css

    你要么把页面的资源路径也写成 book/static/?.css
    要么找个插件在 nginx 上把后端 proxy 对象返回的页面里的对应资源路径给 rewrite 了.
    coolfan
        6
    coolfan  
       15 小时 8 分钟前   ❤️ 1
    不行,对 url 的 path 匹配必须要求应用程序本身考虑到这个行为并适配。

    比如有些网页请求的资源是/static/main.js, 虽然你访问的是 abc.com/book/ 但是浏览器还是会访问 abc.com/static/main.js

    用子域名可以完美解决,book.abc.com 对应 book ; film.abc.com 对应 film 。 写多个 server ,其中的 server_name 配置对应的子域名
    oouz
        7
    oouz  
       15 小时 3 分钟前
    是不是需要换一下 /book 和 / 配置的位置,把/book 换到 / 的前面去。
    我记得之前看到过好像这个配置的匹配是按顺序匹配,你现在/ 放在最前面,不管是 abc.com:10086 还是 abc.com:10086/book 都会被 / 匹配成功。所以都走的 192.168.0.100:10086

    把这两个换一下位置试试?
    jadeborner
        8
    jadeborner  
       14 小时 58 分钟前
    前端 publicpath 加上 book
    ltaoo1o
        9
    ltaoo1o  
       14 小时 57 分钟前
    上面的人已经说到根本原因了,静态网站需要做一些配置,如果是 `vite` 项目, `base` 需要配置为 `/book`。

    我刚好有一个这种项目,我分别有 `/pc`、`/mobile` 两个网站,通过 `www.domain.com/pc` 和 `www.domian.com/mobile` 访问,我的目录结构如下

    ```
    apps
    - flix_prod_web
    - pc
    index.html
    static
    - mobile
    index.html
    static
    ```

    nginx 配置

    ```
    location /mobile {
    alias /apps/flix_prod_web/mobile;
    try_files $uri $uri/ /mobile/index.html;
    }
    location /pc {
    alias /apps/flix_prod_web/pc;
    try_files $uri $uri/ /pc/index.html;
    }
    ```

    前端我用了 `browser history`,这样可以保证刷新时不会 404 。

    我是问 GPT 实现的,具体原理我也不懂。
    JayZXu
        10
    JayZXu  
       14 小时 53 分钟前
    只用 nginx 是无法实现这个分流的
    核心原因在于编译好的前端去请求地址时是写死的,你代理的两个地址实际上只区分的入口,即 index.html 。但是后续请求的接口和静态资源没办法区分了

    前端是自己写的,可以通过修改 publicpath 或者 base 参数重新打包

    不是自己写的,要么通过域名在 nginx 做 server_name 分流,要么本地写 host 实现主机名访问再通过 nginx 的 server_name 分流
    guoguobaba
        11
    guoguobaba  
       14 小时 47 分钟前
    https://zhuanlan.zhihu.com/p/577030920

    原理和这个比较类似
    wxd21020
        12
    wxd21020  
       14 小时 42 分钟前
    兄弟,上 lucky ,搜一下 lucky
    partner666
        13
    partner666  
       14 小时 33 分钟前
    你想实现的效果需要在前端改,或者这样? location /book {
    proxy_pass http://192.168.0.100:10010/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    }
    R77
        14
    R77  
       13 小时 33 分钟前
    location ~ ^/(js|css|images)/ {
    proxy_pass http://xxx;
    }

    可以试试,类似的
    AndreasG
        15
    AndreasG  
    OP
       11 小时 59 分钟前
    @JayZXu 多谢老哥
    AndreasG
        16
    AndreasG  
    OP
       11 小时 58 分钟前
    @R77 我试了一下静态地址请求拼接的方式,静态文件都加载成功了,您这个方式获取静态资源是完全可行的,但是由于还有后端接口貌似不通,最后使用了二级域名解决了这个问题,多谢老哥解答
    AndreasG
        17
    AndreasG  
    OP
       11 小时 57 分钟前
    @partner666 当时试了一下,还是不太行,貌似不符合我这个情况,不过多谢帮助!
    AndreasG
        18
    AndreasG  
    OP
       11 小时 55 分钟前
    @wxd21020 卧槽我搜了一下感觉这个好用啊,从来没听说过,学到了老哥
    AndreasG
        19
    AndreasG  
    OP
       11 小时 54 分钟前
    @guoguobaba 貌似最底层原因是这个,但是前端项目我没法改,多谢老哥
    AndreasG
        20
    AndreasG  
    OP
       11 小时 53 分钟前
    @ltaoo1o 我查了查貌似要改前端东西,不过我这不好改,不过多谢老哥
    AndreasG
        21
    AndreasG  
    OP
       11 小时 52 分钟前
    @coolfan 多谢老哥,我最后采用了你的方法,使用了二级域名绕过这个问题
    AndreasG
        22
    AndreasG  
    OP
       11 小时 51 分钟前
    @zizon 貌似有点走远了,我查了查要彻底解决貌似是要改改,不过我这项目是弄好的 docker 不好改了,不过多谢
    AndreasG
        23
    AndreasG  
    OP
       11 小时 50 分钟前
    @oouz 试了试不太行,貌似不是这个原因,不过已经解决,多谢老哥协助
    AndreasG
        24
    AndreasG  
    OP
       11 小时 50 分钟前
    @sagaxu 多谢老哥协助
    coolloves
        25
    coolloves  
       11 小时 4 分钟前
    proxy_redirect http://192.168.0.100:10086/ /book/;

    试试呢
    coolloves
        26
    coolloves  
       11 小时 3 分钟前
    location /book {
    proxy_pass http://192.168.0.100:10010;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_redirect http://192.168.0.100:10010/ /book/;
    }
    lovelylain
        27
    lovelylain  
       8 小时 22 分钟前 via Android
    @coolloves proxy_redirect 解决的只是 header location 跳转,网页里用了绝对路径还是会有问题的,能重新构建网页的话可以改为使用相对路径,不能的话用 sub_filter 替换运气好也能搞定,但是很麻烦
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1008 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 20:23 · PVG 04:23 · LAX 12:23 · JFK 15:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.