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

使用Nginx在Docker网络中代理内部端口相同的两个React应用

问题分析与解决建议

核心问题

出现502错误的直接原因是Nginx配置中/app-b的proxy_pass指向了宿主机暴露的端口3001,而非容器内部的端口3000。在Docker同一网络内,容器间通信需使用目标容器的内部监听端口,而非宿主机的端口映射值。

应用B的容器内部实际监听端口是3000,宿主机的3001只是映射到容器3000的外部入口,仅用于宿主机外部访问,不适用于容器间的直接通信。

正确解决方案

1. 修正Nginx配置

修改default.conf中/app-b的proxy_pass为容器内部端口:

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

   location /app-a {
      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_pass http://app-a:3000;
   }

   location /app-b {
      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_pass http://app-b:3000;  # 改为容器内部端口3000
   }
     
}

修改后重启Nginx容器生效。

2. 解决React应用的子路径适配问题

即使修复了Nginx代理,React应用可能仍会出现静态资源加载失败的情况(默认假设部署在根路径/)。需在构建React应用时指定PUBLIC_URL:

  • 构建应用A时:
    PUBLIC_URL=/app-a npm run build
    
  • 构建应用B时:
    PUBLIC_URL=/app-b npm run build
    

重新构建并部署两个React应用的Docker镜像,确保静态资源路径自动带上/app-a或/app-b前缀。

3. 确认容器网络归属

确保三个容器(app-a、app-b、nginx)确实处于同一Docker网络中:

docker network inspect <你的网络名称>

检查输出中的Containers字段,确认三个容器都在列表内。若不在,需将容器重新连接到同一网络:

docker network connect <你的网络名称> <容器名称>

为什么临时方案不规范

  • 使用http://my-ip:3001代理:流量会从Nginx容器流出到宿主机,再通过端口映射回到app-b容器,绕开了Docker内部网络,效率更低且不符合容器间通信的最佳实践。
  • 为应用B构建不同端口的镜像:完全没必要,Docker的端口映射功能就是为了解决同一宿主机上容器端口冲突的问题,无需修改镜像本身。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:16:20