# 单端口入口(默认对外 5051) # # 用途:把管理端、文档站、OpenAPI 收在一个端口下,便于在外部网关 / DNS # 只暴露一个地址。编排里由 gateway 服务(profile: with-gateway)加载本文件, # 容器内监听 80,宿主机发布端口用 GATEWAY_PORT 控制(默认 5051)。 # # docker compose --profile with-gateway up -d # GATEWAY_PORT=8088 docker compose --profile with-gateway up -d # # 路由: # / -> 管理端(admin-ui,内部已代理 /api/ 到 admin-svr) # /docs/ -> 文档站(docs) # /www/ -> 官网(website,需启用 with-website profile) # /openapi/ -> 对外 API(openapi) # /route/open/ -> 运营商能力代理(openapi) # # 小程序 / H5 端的静态资源是根路径部署的,不能挂在同一域名的子路径下, # 需要单独域名或单独端口(见 config/nginx/iotlcm.conf 的 app 段)。 # DNS 解析:nginx 默认只在启动时把 upstream 主机名解析一次,容器重建/重启换了 IP # 就一直往旧地址打(2026-11-03 踩到:整站 /openapi 全 502,重启网关才恢复)。 # 127.0.0.11 是 Docker 内置 DNS;下面的 resolve + zone 让它在运行期自动跟随。 resolver 127.0.0.11 valid=10s ipv6=off; upstream gw_admin_ui { zone gw_admin_ui 64k; server admin-ui:80 resolve; } upstream gw_openapi { zone gw_openapi 64k; server openapi:8000 resolve; } upstream gw_docs { zone gw_docs 64k; server docs:80 resolve; } # 官网(可选组件,profile with-website)。容器未启动时该路径返回 502, # 不影响其它路径;resolve 让容器 IP 变化后自动跟随。 upstream gw_website { zone gw_website 64k; server website:80 resolve; } server { listen 80; charset utf-8; client_max_body_size 200m; access_log /var/log/nginx/access_gateway.log; error_log /var/log/nginx/error_gateway.log; proxy_http_version 1.1; 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_read_timeout 120s; proxy_send_timeout 120s; # ---------- 文档站 ---------- location = /docs { return 301 /docs/; } location ^~ /docs/ { proxy_pass http://gw_docs; } # ---------- 官网(子路径形态) ---------- # 官网以 SITE_BASE=/www/ 构建时,资源引用是 /www/assets/..., # 所以这里不能剥前缀(proxy_pass 不带尾斜杠),由官网容器内的 # alias 规则自己剥。域名定下来后改用独立 vhost,这段可删。 location = /www { return 301 /www/; } location ^~ /www/ { proxy_pass http://gw_website; } # ---------- 对外 API:版本化接口 ---------- location ^~ /openapi/ { proxy_pass http://gw_openapi; } # ---------- 对外 API:运营商能力代理(白名单 / 共享 Token)---------- location ^~ /route/open/ { proxy_pass http://gw_openapi; } # ---------- 管理端(含 /api/ 与 /upload/,由 admin-ui 自行转发)---------- location / { proxy_pass http://gw_admin_ui; } gzip on; gzip_min_length 1k; gzip_types text/plain text/css application/json application/javascript application/xml image/svg+xml; }