Nginx 配置管理规范
一、文档说明本文档基于当前 SPC 工业平台完整 Docker 微服务架构编写适用于项目统一入口 Nginx 反向代理网关。覆盖内容Nginx 容器架构说明、目录结构、完整配置、启停重载、配置更新、故障排查、子路径代理、WebSocket 转发、API 网关转发、生产运维规范。适配架构Docker Compose 双网络public-net 外网访问、internal-net 服务内网二、Nginx 网关架构概述1. 核心定位Nginx 作为项目统一流量入口承载所有前端页面、后端 API、WebSocket 长连接的反向代理统一对外暴露 80/443 端口实现动静分离、路由分发、路径重写、跨域代理。2. 网络模式说明public-net桥接外网Nginx、前端服务、网关服务暴露外网可访问端口internal-net私有内网所有后端微服务内网互通不对外暴露保障服务安全3. 代理业务清单主前端 SPC.Web根路径 / 与子路径 /spc-web/ 双访问适配3D 可视化前端 SPC.3D子路径 /spc-3d/ 访问WebSocket 实时长连接/ws/ 路由转发至 API 网关全局 API 接口/api/ 统一转发至网关服务 55000 端口三、Nginx 部署目录结构部署根目录与 docker-compose.yml 同级./proxy ├── nginx │ └── conf.d/ # 站点配置目录所有代理规则存放处 │ └── default.conf # 核心代理配置文件 └── ssl/ # HTTPS 证书存放目录ocker中网关必须有如下内容// WS路由精确匹配 /ws/xxx 高优先级 { DownstreamPathTemplate: /{everything}, DownstreamScheme: ws, DownstreamHostAndPorts: [ { Host: spcoverviewservice, Port: 9019 } ], UpstreamPathTemplate: /ws/{everything}, UpstreamHttpMethod: [ GET ], Priority: 10 }, // WS兜底纯/ws 根路径 { DownstreamPathTemplate: /, DownstreamScheme: ws, DownstreamHostAndPorts: [ { Host: spcoverviewservice, Port: 9019 } ], UpstreamPathTemplate: /ws/, UpstreamHttpMethod: [ GET ], Priority: 5 }四、Docker Compose Nginx 服务配置以下为项目生产可用 Nginx 完整服务配置集成日志、时区、挂载、依赖、网络策略。version: 3.8 networks: public-net: driver: bridge internal-net: external: true services: # 统一入口Nginx网关 proxy: image: 10.31.20.10:8081/build-tools/nginx:1.25 container_name: spc-proxy restart: always ports: - 56000:80 - 443:443 volumes: - ./proxy/nginx/conf.d:/etc/nginx/conf.d - ./proxy/ssl:/etc/nginx/ssl environment: - TZAsia/Shanghai networks: - public-net depends_on: - spc-web - spc-3d - spcwebgateway # 主前端应用 spc-web: image: 10.31.20.10:8081/sensesmill-docker/spc.web:beta container_name: spc-web restart: always expose: - 80 volumes: - ./web/spc.web/app-config/app-config.prod.json:/usr/share/nginx/html/assets/file/app-config/app-config.prod.json environment: - TZAsia/Shanghai networks: - public-net # 3D可视化前端 spc-3d: image: 10.31.20.10:8081/sensesmill-docker/spc.3d:beta container_name: spc-3d restart: always expose: - 80 volumes: - ./web/spc.3d/app-config/config.json:/usr/share/nginx/html/config/config.json - ./web/spc.3d/app-config/dataConfig.json:/usr/share/nginx/html/config/dataConfig.json environment: - TZAsia/Shanghai networks: - public-net # API网关服务 spcwebgateway: image: 10.31.20.10:8081/sensesmill-docker/spcwebgateway:beta container_name: spcwebgateway restart: always ports: - 55000:80 - 55443:443 volumes: - ./spcwebgateway/Logs:/app/Logs - ./spcwebgateway/config/appsettings.json:/app/appsettings.json - ./spcwebgateway/config/ocelot.json:/app/ocelot.json environment: - TZAsia/Shanghai - ASPNETCORE_URLShttp://:80 logging: driver: json-file options: max-size: 10m max-file: 31 healthcheck: test: [CMD, curl, -f, http://localhost:80/Health] interval: 30s timeout: 10s retries: 3 start_period: 60s networks: - public-net - internal-net # 认证授权中心 spcplantdataservice-authserver: image: 10.31.20.10:8081/sensesmill-docker/spcplantdataservice-authserver:beta container_name: spcplantdataservice-authserver restart: always ports: - 55001:80 volumes: - ./spcplantdataservice-authserver/Logs:/app/Logs - ./spcplantdataservice-authserver/config/appsettings.json:/app/appsettings.json environment: - TZAsia/Shanghai - ASPNETCORE_URLShttp://:80 logging: driver: json-file options: max-size: 10m max-file: 31 healthcheck: test: [CMD, curl, -f, http://localhost:80/Health] interval: 30s timeout: 10s retries: 3 start_period: 60s networks: - public-net - internal-net # 工厂基础数据服务 spcplantdataservice: image: 10.31.20.10:8081/sensesmill-docker/spcplantdataservice:beta container_name: spcplantdataservice restart: always ports: - 55002:80 volumes: - ./spcplantdataservice/Logs:/app/Logs - ./spcplantdataservice/config/appsettings.json:/app/appsettings.json - ./spcplantdataservice/BlobStoreFiles:/app/BlobStoreFiles - ./spcplantdataservice/file:/app/file environment: - TZAsia/Shanghai - ASPNETCORE_URLShttp://:80 logging: driver: json-file options: max-size: 10m max-file: 31 healthcheck: test: [CMD, curl, -f, http://localhost:80/Health] interval: 30s timeout: 10s retries: 3 start_period: 60s networks: - public-net - internal-net配置说明镜像私有仓库 Nginx1.25 稳定版端口映射外网 56000 映射容器80443 用于HTTPS配置挂载本地 conf.d 目录挂载容器配置目录支持热更新证书挂载统一存放 SSL 证书文件依赖启动优先等待前端、网关服务启动后再启动 Nginx网络隔离仅接入外网网络不直接接入内网服务网络提升安全性五、Nginx 核心代理配置default.conf适配项目子路径访问、静态资源重写、WebSocket、API转发完整配置可直接覆盖使用。server { listen 80; server_name _; # SPC.Web - 根路径保持原样 location / { proxy_pass http://spc-web:80; 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; } # SPC.Web - 子路径访问新增 location /spc-web/ { proxy_pass http://spc-web:80/; 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; # 替换 HTML 中的路径前缀如果 spc-web 使用根路径引用资源 sub_filter base href/ base href/spc-web/; sub_filter src/ src/spc-web/; sub_filter href/ href/spc-web/; sub_filter_once off; } # SPC.3D - 子路径访问 location /spc-3d/ { proxy_pass http://spc-3d:80/; 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; sub_filter base href/ base href/spc-3d/; sub_filter src/ src/spc-3d/; sub_filter href/ href/spc-3d/; sub_filter_once off; } # WebSocket location /ws/ { proxy_pass http://spcwebgateway:80; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_read_timeout 3600s; } # API location /api/ { proxy_pass http://spcwebgateway:80; 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_connect_timeout 120s; proxy_read_timeout 120s; } }或者直接挂载nginx.conf# ------------------------ # Docker容器内Nginx 80端口网关主机配置 # 作用统一入口反向代理内部各业务容器spc-web/spc-3d/spcwebgateway # 容器网络内可直接通过容器名作为域名通信无需宿主机IP # ------------------------ server { # 容器内监听80端口对外由docker端口映射暴露访问 listen 80; # 匹配所有访问域名不限制前端访问域名 server_name _; # # 1. SPC.Web前端容器 - 根路径访问 # 外部访问地址http://宿主机IP/ # 转发目标同Docker网络内 spc-web 容器80端口 # proxy_pass 末尾无斜杠完整保留客户端原始请求路径转发给前端容器 # location / { proxy_pass http://spc-web:80; # 透传客户端原始访问域名前端/后端可获取真实Host proxy_set_header Host $host; # 传递客户端真实公网IP宿主机转发场景日志溯源用 proxy_set_header X-Real-IP $remote_addr; # 多级代理链路完整IP记录 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 透传当前访问协议 http/https适配鉴权、跳转逻辑 proxy_set_header X-Forwarded-Proto $scheme; } # # 2. SPC.Web前端容器 - 子路径 /spc-web/ 访问 # 外部访问地址http://宿主机IP/spc-web/ # 场景前端打包仅适配根路径 /无法重新打包用sub_filter动态替换HTML内资源路径 # Docker容器代理必须双关闭压缩gzip off 清空Accept-Encoding防止上游容器返回压缩HTML导致替换失效 # proxy_pass末尾带/自动截断URL前缀/spc-web/转发给spc-web容器根路径 # location /spc-web/ { proxy_pass http://spc-web:80/; # 透传客户端请求基础信息头 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; # 【Docker代理关键配置】局部关闭当前location的gzip压缩 gzip off; # 清空Accept-Encoding请求头告知上游spc-web容器不要返回gzip压缩包保证HTML明文输出 proxy_set_header Accept-Encoding ; # 替换页面基础路由基准标签所有资源/路由以 /spc-web/ 为根 sub_filter base href/ base href/spc-web/; # 替换JS/CSS/图片静态资源绝对路径避免404 sub_filter src/ src/spc-web/; # 替换页面内a标签跳转链接防止路由丢失子路径前缀 sub_filter href/ href/spc-web/; # sub_filter_once off页面内所有匹配文本全部替换不止替换第一个 sub_filter_once off; } # # 3. SPC.3D可视化前端容器 - 子路径 /spc-3d/ 访问 # 外部访问地址http://宿主机IP/spc-3d/ # 逻辑同/spc-web/适配子目录部署关闭压缩保障HTML字符串替换生效 # 转发目标Docker内网 spc-3d 容器80端口 # location /spc-3d/ { proxy_pass http://spc-3d:80/; # 透传客户端请求头 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; # 【Docker代理关键配置】关闭压缩获取明文HTML用于路径替换 gzip off; proxy_set_header Accept-Encoding ; # 替换3D页面全部根路径引用适配/spc-3d/子目录访问 sub_filter base href/ base href/spc-3d/; sub_filter src/ src/spc-3d/; sub_filter href/ href/spc-3d/; sub_filter_once off; } # # 4. WebSocket长连接代理 /ws/ # 转发目标网关容器 spcwebgateway:80 # 业务场景实时数据推送、设备监控、在线消息、3D实时联动 # Docker容器间WebSocket必须开启HTTP/1.1、协议升级、延长读写超时 # location /ws/ { proxy_pass http://spcwebgateway:80; # WebSocket协议升级强制依赖HTTP/1.1HTTP1.0不支持 proxy_http_version 1.1; # 标记协议升级HTTP 切换 WebSocket proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; # 长连接空闲超时1小时避免容器间ws连接被nginx主动断开 proxy_read_timeout 3600s; } # # 5. 后端API接口统一代理 /api/ # 所有业务接口统一转发至网关容器 spcwebgateway:80 # 延长超时时间适配大数据导出、报表慢查询、复杂生产计算接口 # location /api/ { proxy_pass http://spcwebgateway:80; # 透传客户端真实IP、访问协议后端鉴权/审计日志使用 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_connect_timeout 120s; # 接口响应读取超时适配耗时业务接口 proxy_read_timeout 120s; } }六、核心功能详解1. 子路径适配原理前端项目默认根路径打包直接子路径访问会出现静态资源404。通过sub_filter动态替换 html 内的 base、src、href 路径实现无需改前端代码Nginx 层自动适配子路径。2. WebSocket 长连接支持开启 HTTP1.1、Upgrade 升级头、超长读取超时1小时适配设备实时数据、报警推送、3D 实时联动场景杜绝长连接断开问题。3. API 统一转发所有前端 /api/ 请求统一转发至后端网关服务 55000 端口由 Ocelot 网关统一路由到各个微服务设备、能耗、报警、生产、质量、时序数据服务。七、日常运维操作命令所有命令在docker-compose.yml 同级目录执行1. 启动 Nginxdocker compose up -d proxy2. 停止 Nginxdocker compose down proxy3. 重启 Nginxdocker compose restart proxy4. 配置热重载重要不重启容器生效修改 nginx 配置后必须执行重载避免重启服务断流# 检查配置语法 docker exec -it spc-proxy nginx -t # 热重载配置 docker exec -it spc-proxy nginx -s reload5. 查看 Nginx 日志# 实时日志 docker logs -f spc-proxy6. 进入容器内部调试docker exec -it spc-proxy bash八、常见故障排查方案1. 子路径访问页面空白、静态资源404原因sub_filter 规则未生效或配置未重载解决检查配置文件、执行nginx -t nginx -s reload2. WebSocket 连接失败、频繁断开原因未开启升级头、超时时间过短解决确认 location /ws/ 配置完整超时时间不低于 3600s3. API 接口 502/504 超时原因代理超时时间不足、网关服务未启动解决调整 proxy 超时参数检查 spcwebgateway 健康状态4. Nginx 启动失败排查步骤检查配置语法docker exec spc-proxy nginx -t检查端口占用80/443/56000检查挂载目录权限九、生产运维规范所有 Nginx 配置修改必须先检查语法再重载禁止直接重启容器前端新增子页面、新服务路由统一在 conf.d 中新增 location 规则SSL 证书过期前提前替换存放至 ./proxy/ssl 目录严禁直接修改容器内配置所有配置通过本地挂载文件管理对外端口统一由 Nginx 暴露后端微服务禁止直接对外开放端口十、附录项目完整代理路由对照表访问路径代理目标服务用途/spc-web:80主系统首页/spc-web/spc-web:80主系统子路径访问/spc-3d/spc-3d:803D可视化页面/ws/spcwebgateway:80实时WebSocket推送/api/spcwebgateway:80所有后端微服务接口