From d489169bec87a4954009502bb1650c6f4ba8b50d Mon Sep 17 00:00:00 2001 From: whm <973418690@qq.com> Date: Fri, 7 Aug 2026 01:23:34 +0800 Subject: [PATCH] fix: host nginx proxies /api to gateway to avoid web DNS 502 Public HTTPS API/AI/gateway go to 127.0.0.1:8180; web only serves static. Restores static gateway upstream inside the web container. Co-authored-by: Cursor --- nginx/README.md | 3 ++- nginx/aijz.host.conf | 53 +++++++++++++++++++++++++++++++------- scripts/lib-aijz-deploy.sh | 4 ++- web/nginx.conf | 3 +-- web/nginx.conf.template | 16 +++++------- 5 files changed, 55 insertions(+), 24 deletions(-) diff --git a/nginx/README.md b/nginx/README.md index 59323b6..efd1be4 100644 --- a/nginx/README.md +++ b/nginx/README.md @@ -8,7 +8,8 @@ AI 建站默认用 **Docker web 容器**(`127.0.0.1:5173`)对外提供页面 | 用途 | 仓库路径 | 生效方式 | |------|----------|----------| -| 容器 Web 反代 | `web/nginx.conf.template` | `./reload-config.sh web` | +| 容器 Web 反代 | `web/nginx.conf.template`(本机 :5173) | `./reload-config.sh web` | +| 公网 API | 宿主机 Nginx `/api/` → `:8180` | `./reload-config.sh` | | Platform | `platform/etc/platform.docker.yaml` | `./reload-config.sh platform` | | Gateway | `gateway/etc/gateway.docker.yaml` | `./reload-config.sh gateway` | | LLM / 视觉 | `.env` | `./reload-config.sh ai` | diff --git a/nginx/aijz.host.conf b/nginx/aijz.host.conf index 1598d4e..4a892c0 100644 --- a/nginx/aijz.host.conf +++ b/nginx/aijz.host.conf @@ -1,15 +1,12 @@ -# 宿主机 Nginx:443 终止 TLS,反代到本机 Docker web(127.0.0.1:5173) -# web 容器内 nginx 已把 /api/、/ai/、/gateway/ 转发到 gateway。 +# 宿主机 Nginx:443 终止 TLS +# - /api/、/ai/、/gateway/ → 本机 gateway(127.0.0.1:8180),避免经 web 容器 DNS 偶发 502 +# - 静态页与其它路径 → web(127.0.0.1:5173) # # 占位符(由 scripts/lib-aijz-deploy.sh 替换): -# __DOMAIN__ 站点域名 -# __WEB_PORT__ 宿主机 web 映射端口(默认 5173) -# __VERIFY_ROOT__ 域名验证文件目录(项目 verify-root/) -# -# 手动部署: -# 1. 证书放到 /etc/ssl/aijianzhan/__DOMAIN__/{fullchain.pem,privkey.pem} -# 2. sudo cp 生成后的 conf 到 /etc/nginx/conf.d/ -# 3. sudo nginx -t && sudo systemctl reload nginx +# __DOMAIN__ 站点域名 +# __WEB_PORT__ 宿主机 web 映射端口(默认 5173) +# __GATEWAY_PORT__ 宿主机 gateway 映射端口(默认 8180) +# __VERIFY_ROOT__ 域名验证文件目录(项目 verify-root/) server { listen 80; @@ -37,6 +34,42 @@ server { add_header Cache-Control "no-store"; } + location /api/ { + proxy_pass http://127.0.0.1:__GATEWAY_PORT__; + 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_set_header Authorization $http_authorization; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + client_max_body_size 128m; + } + + location /ai/ { + proxy_pass http://127.0.0.1:__GATEWAY_PORT__; + 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_set_header Authorization $http_authorization; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + client_max_body_size 128m; + } + + location /gateway/ { + proxy_pass http://127.0.0.1:__GATEWAY_PORT__; + 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 60s; + } + location / { proxy_pass http://127.0.0.1:__WEB_PORT__; proxy_http_version 1.1; diff --git a/scripts/lib-aijz-deploy.sh b/scripts/lib-aijz-deploy.sh index 94dcf21..801df53 100755 --- a/scripts/lib-aijz-deploy.sh +++ b/scripts/lib-aijz-deploy.sh @@ -112,8 +112,9 @@ install_host_nginx_site_conf() { [ "${AIJZ_ENABLE_HOST_NGINX:-0}" = "1" ] || return 0 local tpl="$ROOT/nginx/aijz.host.conf" local out="/etc/nginx/conf.d/aijz_${domain}.conf" - local web_port + local web_port gw_port web_port="$(publish_host_port "${AIJZ_WEB_PUBLISH:-127.0.0.1:5173}")" + gw_port="$(publish_host_port "${AIJZ_GATEWAY_PUBLISH:-127.0.0.1:8180}")" [ -f "$tpl" ] || { echo "未找到 $tpl,跳过宿主机 Nginx 配置" >&2 return 0 @@ -122,6 +123,7 @@ install_host_nginx_site_conf() { sync_ssl_certs sed -e "s|__DOMAIN__|${domain}|g" \ -e "s|__WEB_PORT__|${web_port}|g" \ + -e "s|__GATEWAY_PORT__|${gw_port}|g" \ -e "s|__VERIFY_ROOT__|${ROOT}/verify-root|g" \ "$tpl" | run_sudo tee "$out" >/dev/null if ! run_sudo nginx -t 2>/dev/null; then diff --git a/web/nginx.conf b/web/nginx.conf index 99af148..7c7c88a 100644 --- a/web/nginx.conf +++ b/web/nginx.conf @@ -1,5 +1,4 @@ -# Dockerfile / 非 compose 场景:静态 upstream(启动时须能解析 gateway)。 -# compose 生产请用 nginx.conf.template + NGINX_ENTRYPOINT_LOCAL_RESOLVERS。 +# Dockerfile / 非 compose:静态 upstream。 server { listen 80; server_name _; diff --git a/web/nginx.conf.template b/web/nginx.conf.template index 012a165..c765428 100644 --- a/web/nginx.conf.template +++ b/web/nginx.conf.template @@ -1,7 +1,6 @@ -# 请求时解析 gateway(避免启动时 DNS 未就绪导致 emerg)。 -# ${NGINX_LOCAL_RESOLVERS} 由官方入口在 NGINX_ENTRYPOINT_LOCAL_RESOLVERS 开启时从 /etc/resolv.conf 注入。 -resolver ${NGINX_LOCAL_RESOLVERS} valid=10s ipv6=off; - +# compose 生产:静态 upstream(启动时解析一次)。 +# 部署脚本在 gateway 就绪后 force-recreate web,避免 DNS 竞态 emerg。 +# 公网流量优先经宿主机 Nginx 直连 gateway(见 nginx/aijz.host.conf),不依赖本文件反代。 server { listen 80; server_name _; @@ -9,8 +8,7 @@ server { index index.html; location /api/ { - set $gw_upstream gateway:8180; - proxy_pass http://$gw_upstream; + proxy_pass http://gateway:8180; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; @@ -20,8 +18,7 @@ server { } location /ai/ { - set $gw_upstream gateway:8180; - proxy_pass http://$gw_upstream; + proxy_pass http://gateway:8180; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Authorization $http_authorization; @@ -29,8 +26,7 @@ server { } location /gateway/ { - set $gw_upstream gateway:8180; - proxy_pass http://$gw_upstream; + proxy_pass http://gateway:8180; proxy_http_version 1.1; proxy_set_header Host $host; }