更新:2026-09-05 16:11

nginx 反向代理与 HTTPS(整站反代)

提供 RuleApi 整站反向代理(含 API + 配置中心静态页共用一个后端端口)的推荐配置。 宝塔面板说明:以下 location ^~ / 整站反代代码,请加入宝塔「网站 → 设置 → 伪静态」中(宝塔伪静态文本框粘贴即可,保存自动写入 nginx 配置;部分版本请粘贴到「配置文件」标签页同位置)。

1. 整站反向代理(推荐配置)

将后端(RuleApi,默认端口 8080)整站代理到站点根路径,同时处理跨域与 WebSocket:

location ^~ / {
  add_header 'Access-Control-Allow-Origin' '*';
  add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
  add_header 'Access-Control-Allow-Credentials' 'true';
  add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Data-Type,X-Requested-With,X-Data-Type,X-Auth-Token';
  if ( $request_method = 'OPTIONS' ) { 
    return 200;
  }
  proxy_pass http://127.0.0.1:8080;
  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 REMOTE-HOST $remote_addr;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_read_timeout 3600s;
  proxy_send_timeout 3600s;
  proxy_buffering off;
}

要点说明:

  • location ^~ / 为前缀匹配整站:站点所有请求(/api/.../apiSystem/.../ 等)统一转发到后端 127.0.0.1:8080;配置中心静态页(见《06》)由后端 Spring Boot 静态资源直接返回,无需单独处理。
  • proxy_pass http://127.0.0.1:8080(无尾斜杠无路径):保留原始路径完整透传(如 /apiSystem/home → 后端 /apiSystem/home)。
  • CORS 头:允许跨域(H5/小程序调试等),OPTIONS 预检直接返回 200。
  • WebSocket 支持Upgrade/Connection "upgrade"(聊天/私信长连接必须)。
  • proxy_read_timeout 3600s:长轮询/大响应场景避免 504。
  • proxy_buffering off:SSE/实时推送场景建议关闭缓冲。

若后端端口不是 8080(如 application.propertiesserver.port=8081),请同步修改 proxy_pass 端口。

2. 宝塔面板操作步骤

  1. 宝塔面板 →「网站」→ 找到该站点 →「设置」。
  2. 切到「伪静态」标签(或「配置文件」标签页)。
  3. 将上方整段配置(location ^~ / {...})粘贴进去并保存。
  4. 若站点已开启 SSL,建议同时在「SSL」中开启强制 HTTPS。

说明:宝塔「伪静态」文本框保存的内容会写入该网站的 nginx 配置;不同宝塔版本界面略有差异(新版在「配置文件」可直接编辑 server 块),效果一致。

3. 完整 server 示例(含 HTTPS)

裸机/自管 nginx(非宝塔)可直接使用:

server {
    listen 80;
    server_name api.example.com;

    location ^~ / {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Data-Type,X-Requested-With,X-Data-Type,X-Auth-Token';
        if ( $request_method = 'OPTIONS' ) {
            return 200;
        }
        proxy_pass http://127.0.0.1:8080;
        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 REMOTE-HOST $remote_addr;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_buffering off;
    }
}

server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate     /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    location ^~ / {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Data-Type,X-Requested-With,X-Data-Type,X-Auth-Token';
        if ( $request_method = 'OPTIONS' ) {
            return 200;
        }
        proxy_pass http://127.0.0.1:8080;
        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 REMOTE-HOST $remote_addr;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_buffering off;
    }
}

# 80 → 443 跳转
server {
    listen 80;
    server_name api.example.com;
    return 301 https://$host$request_uri;
}

4. HTTPS(certbot 一键)

sudo certbot --nginx -d api.example.com

宝塔面板:站点「SSL」→「Let's Encrypt」申请并开启强制 HTTPS 即可。

5. 文档站(docs)放置建议

文档站(docs/,PHP)与 RuleApi 建议使用不同站点/域名(如 docs.example.com),原因:

  • 整站反代 location ^~ / 会把站点全部请求交给后端,与 PHP 文档站同根时会冲突。
  • 独立站点时,文档站走 PHP(宝塔建站默认支持 PHP),RuleApi 站点走上方反代配置。

若必须在同一域名:可将 RuleApi 挂在子路径(如 /api/),文档站占根路径——此时改用 location /api/ 而非 ^~ /(但配置中心需单独 location,见《06》说明,非推荐)。

6. 常见问题

  • 502:后端未启动或 proxy_pass 端口不对(curl 127.0.0.1:8080 验证;后端端口见 application.properties server.port)。
  • OPTIONS 预检失败:确认 if ($request_method = 'OPTIONS') { return 200; } 存在且无拼写错误(注意空格)。
  • WebSocket 连不上:确认 Upgrade/Connection "upgrade" 两行已配置;宝塔部分版本需在「配置文件」里保留(伪静态框有时会被覆盖)。
  • 长响应超时proxy_read_timeout 3600s 未生效时改为在「配置文件」中设置。
  • 跨域仍报 CORS:清浏览器缓存;确认响应头确实带 Access-Control-Allow-*(开发者工具 Network → Response Headers)。
  • 改完配置执行 nginx -t && nginx -s reload(宝塔保存即生效)。