You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker环境下Nginx反向代理多React应用SSL配置故障排查

解决Nginx SSL配置后反向代理React应用失败的问题

我来帮你分析下这个问题,从你提供的错误日志一眼就能找到根源:Nginx正在尝试用HTTPS协议连接上游的app1和app2服务,但你的这两个React应用本身并没有配置SSL,完全是运行在HTTP协议下的。

看日志里的关键信息:upstream: "https://192.168.160.2:5000/app2",明明你在Nginx配置里写的proxy_pass是http://app1:5000,怎么突然变成HTTPS了?这大概率是因为你的React应用在生产环境下被配置了强制HTTPS重定向,当Nginx把外部的HTTPS请求转成HTTP转发给应用时,应用返回了301/302重定向到HTTPS版本的地址,而Nginx默认会自动跟随这个重定向,结果就跑去用HTTPS连接只支持HTTP的上游服务,自然就触发了SSL握手失败的错误。

下面是具体的解决方案,分三步来处理:

1. 取消React应用的强制HTTPS配置

对于用Create React App构建的应用,生产环境下如果设置了HTTPS=true环境变量,会强制应用使用HTTPS。你需要在docker-compose.yml里明确禁用这个设置:

services:
  app1:
    stdin_open: true
    build: app1/app1
    networks:
      - local-network
    environment:
      - NODE_ENV=production
      - PORT=5000
      - HTTPS=false  # 新增这一行,确保应用不强制HTTPS
  app2:
    stdin_open: true
    build: app2/app2
    networks:
      - local-network
    environment:
      - NODE_ENV=production
      - PORT=5000
      - HTTPS=false  # 同样新增这一行

如果是用其他工具(比如serve)部署的React应用,检查启动命令里有没有强制HTTPS的参数,直接去掉即可。

2. 优化Nginx配置,修正重定向问题

在Nginx的每个location块里添加proxy_redirect指令,确保上游返回的HTTPS重定向被修正为正确的路径,避免Nginx错误地用HTTPS连接上游:

location /app1 {
    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_pass http://app1:5000;
    # 新增这一行,修正上游的HTTPS重定向
    proxy_redirect https://$host http://$host;
    # WebSocket support
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}
location /app2 {
    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_pass http://app2:5000;
    # 新增这一行
    proxy_redirect https://$host http://$host;
    # WebSocket support
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

另外,你已经设置了X-Forwarded-Proto $scheme,这个很重要,它能让React应用感知到外部请求是通过HTTPS进来的,不会因为觉得自己在HTTP环境而触发不必要的重定向。

3. 提前处理React应用的子路径路由问题

虽然这和当前的SSL握手问题无关,但因为你是通过/app1和/app2的子路径访问应用,不配置的话后续会出现静态资源加载失败的问题:

  • 在React应用的路由配置里,给BrowserRouter添加basename属性:
    import { BrowserRouter } from 'react-router-dom';
    
    ReactDOM.render(
      <BrowserRouter basename="/app1">
        <App />
      </BrowserRouter>,
      document.getElementById('root')
    );
    
  • 构建应用时设置PUBLIC_URL环境变量,比如:
    PUBLIC_URL=/app1 npm run build
    

最后验证

修改完成后,重启你的Docker服务:

docker-compose down && docker-compose up --build -d

然后访问https://xxx.xxx.xxx.xx/app1和https://xxx.xxx.xxx.xx/app2,应该就能正常访问了。

内容的提问来源于stack exchange,提问作者Fiphe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 18:22:33