<p>Revel 生产环境必须用 Nginx 反向代理,绑定 127.0.0.1 而非 0.0.0.0;proxy_pass 需带尾部斜杠,且必须设置 X-Forwarded-* 头(尤其 X-Forwarded-Proto),HTTPS 终结应在 Nginx 层。</p>

Revel 应用不该直接暴露端口(比如 :8089),必须用 Nginx 做反向代理——这不是可选项,是生产环境的底线。
Revel 启动时必须绑定 127.0.0.1,不能用 0.0.0.0
Revel 默认启动会监听 0.0.0.0:8089,这等于把服务直接扔到公网可访问范围。Nginx 反向代理的前提是后端只对本机开放。
- 启动 Revel 应用时显式指定地址:
revel run myapp -a 127.0.0.1:8089 - 或修改
conf/app.conf中的http.addr = "127.0.0.1"和http.port = "8089" - 验证是否生效:
ss -tln | grep :8089,输出里应该只有127.0.0.1:8089,没有*:8089
proxy_pass 地址末尾斜杠决定路径重写行为
Revel 路由是基于根路径(/)设计的,如果 proxy_pass 写成 http://127.0.0.1:8089/(带尾部斜杠),Nginx 会剥离 location / 的前缀再转发;不带斜杠则原样转发,可能导致 404。
- 正确写法(推荐):
proxy_pass http://127.0.0.1:8089/;(注意结尾斜杠) - 错误写法:
proxy_pass http://127.0.0.1:8089;(没斜杠,Revel 收到的请求 URI 会多出一层路径) - 如果你用了子路径代理(如
location /api/),那proxy_pass必须不带斜杠,并手动用rewrite或proxy_redirect处理,但 Revel 不推荐这种部署方式
必须设置 X-Forwarded-* 头,否则 Revel 拿不到真实 IP 和协议
Revel 的 Req.RemoteAddr、Req.Referer()、Req.URL.Scheme 等都依赖 Nginx 传来的原始信息。不设这些头,你会看到所有请求 IP 是 127.0.0.1,HTTPS 判断失败,重定向出错。
- 至少要加这四行:
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; - Revel 的
app.Init()里默认信任X-Forwarded-For,但前提是 Nginx 在内网可信链路中——所以务必确保 Revel 只监听127.0.0.1,杜绝绕过 Nginx 的直连可能 - 如果启用了 HTTPS,
X-Forwarded-Proto决定 Revel 生成的绝对 URL 是http://还是https://,漏掉它会导致登录跳转回 HTTP
HTTPS 终结必须在 Nginx 层,Revel 保持 HTTP 内部通信
让 Revel 自己处理 TLS 是低效且危险的:证书续期麻烦、私钥暴露风险高、HTTP/2 支持弱。Nginx 做 SSL 终结才是标准做法。
- Nginx 配置里开
listen 443 ssl,填好ssl_certificate和ssl_certificate_key - Revel 应用仍跑在
http://127.0.0.1:8089,不做任何 TLS 配置 - 关键点:
proxy_set_header X-Forwarded-Proto $scheme;必须存在,否则 Revel 无法感知外层是 HTTPS - 别在 Revel 里调用
req.TLS != nil判断协议,它永远为nil—— 正确方式是读req.Header.Get("X-Forwarded-Proto") == "https"
最容易被忽略的是 proxy_pass 尾部斜杠和 X-Forwarded-Proto 的组合:一个写错,整个应用的重定向、CSRF Token、静态资源链接全乱套,但错误现象分散,很难一眼定位到 Nginx 配置上。


















