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

Docker Swarm中Nginx反向代理无法获取完整React包的问题

问题排查:Docker Swarm中Nginx反向代理React应用出现响应异常

环境与异常现象

  • 部署环境:Docker Swarm工作节点,nginx:1.22.1与静态React应用服务器绑定同一节点,通过自定义overlay网络通信;Swarm加入时指定数据中心内部地址为advertise address,服务可通过公网访问
  • 核心异常:
    • 直接公网访问React应用可获取完整资源包,但通过Nginx反向代理时,Chrome浏览器报net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK),JS包在函数中途被截断
    • 偶尔上游服务器返回HTML而非预期的JS包,该响应完整无截断

Nginx配置文件(/etc/nginx/conf.d/default.conf)

resolver 127.0.0.11 valid=10s;
error_log /dev/stdout info;

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen 80;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    ssl_certificate /etc/nginx/certs/nginx.pem;
    ssl_certificate_key /etc/nginx/certs/key.pem;
    client_max_body_size 100M;
    proxy_buffers 8 1024k;
    proxy_buffer_size 1024k;
    proxy_max_temp_file_size 1024m;

    location / {
        set $reactapp reacthost;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://$reactapp:3000/;
        proxy_redirect off;
    }
        root /usr/share/nginx/html;
    }

    error_page 500 502 503 504 /50x.html;
}

容器启动日志

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?)

已知信息

  • 用$reactapp变量实现Nginx启动后的DNS服务发现
  • Nginx以nginx用户运行,exec进入容器后,该用户可访问/var/cache/nginx/并创建目录
  • 此前通过bridge网络部署时,Nginx在上游服务启动后启动,反向代理工作正常;Docker Stack不支持depends_on,依赖DNS服务发现

怀疑方向

  • Nginx服务器/location配置存在语法或逻辑错误
  • Stack模式下Nginx无法写入容器所需路径
  • overlay网络存在连通性问题,导致上游服务访问异常

排查与解决方法

1. 修复Nginx配置语法错误

当前配置存在明显的语法问题:root /usr/share/nginx/html;的缩进和server块闭合错误,会导致Nginx运行逻辑混乱,是响应异常的核心原因之一。修正后的server块如下:

server {
    listen 443 ssl;
    ssl_certificate /etc/nginx/certs/nginx.pem;
    ssl_certificate_key /etc/nginx/certs/key.pem;
    client_max_body_size 100M;
    proxy_buffers 8 1024k;
    proxy_buffer_size 1024k;
    proxy_max_temp_file_size 1024m;

    root /usr/share/nginx/html;

    location / {
        set $reactapp reacthost;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade; # 使用定义好的变量替代硬编码,适配WebSocket场景
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://$reactapp:3000/;
        proxy_redirect off;
    }

    error_page 500 502 503 504 /50x.html;
}

2. 解决只读文件系统问题

启动日志提示无法修改default.conf,处理方案:

  • 在Docker Stack的compose文件中,确认未将/etc/nginx/conf.d/挂载为只读卷
  • 添加环境变量DISABLE_IPV6=1,禁用10-listen-on-ipv6-by-default.sh脚本,避免其尝试修改配置文件
  • 若使用自定义镜像,构建时确保/etc/nginx/conf.d/目录权限为nginx用户可读写

3. 验证Overlay网络与服务发现

  • 进入Nginx容器,执行nslookup reacthost,确认能正确解析到React应用容器的IP
  • 多次执行curl http://reacthost:3000/static/js/main.xxx.js,检查返回内容是否完整、是否偶尔返回HTML,排除上游服务本身的问题
  • 在两个容器中互相ping对方的服务名/IP,确认overlay网络连通性稳定

4. 优化Nginx代理缓冲设置

  • 添加proxy_cache_bypass $http_upgrade;,避免WebSocket请求被缓存
  • 确保proxy_buffering on;(默认开启),保证Nginx能正确处理上游返回的chunked编码响应
  • 临时设置proxy_max_temp_file_size 0;,禁止使用临时文件存储响应,排查是否因磁盘写入问题导致截断

5. 替代depends_on确保服务启动顺序

Docker Stack不支持depends_on,可通过以下方式确保React服务先就绪:

  • 在Nginx的启动脚本中添加健康检查逻辑,等待reacthost:3000可访问后再启动Nginx
  • 在React服务的compose配置中添加healthcheck,同时在Nginx配置中添加proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;,自动重试未就绪的上游服务

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:40:49