1. 开启 force_https(Discourse)
- 让站点一律走 HTTPS,并给 Cookie 加上 Secure,配合 NPM 传入的协议头使用。
./launcher enter app
rails r "SiteSetting.force_https = true"
exit
备注:这与 CSP 不同;force_https 负责重定向,CSP 负责前端资源白名单。
2. 启用 HSTS(NPM)与 CSP(Discourse)
- HSTS:在 NPM → Proxy Host → SSL 勾选
Force SSL / HTTP/2 / HSTS / OCSP Stapling(HSTS 会在响应头里体现为strict-transport-security)。 - CSP(内容安全策略):建议开启(如果之前为排错临时关闭过):
./launcher enter app
rails r "SiteSetting.content_security_policy = true"
exit
提醒:不要在 NPM 的 Advanced 里再手工添加 CSP 头,避免与 Discourse 自带的 CSP 冲突。
3. NPM → Proxy Host → Advanced(只保留必要请求头)
不要在这里写 301/302/重写规则,也不要加 CSP。
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
并在 Proxy Host 勾选:Websocket Support。
4. www → 非 www 用 Redirect Host 实现
让规范域名收敛到 abc.com,避免在 Proxy Host 里自写 301 造成双跳。
- 类型:重定向
- 域名:
www.abc.com - 转发域名:
abc.com - Http代码:
301 Permanent(永久重定向,SEO 友好) - 保留路径:✔
- 阻止常见漏洞:✔
- 强制 SSL:✔
5. (强烈推荐)容器网络与目标主机名的规范
解决“偶发空白/样式错乱/循环”的根因之一是 Docker 内部 DNS 名称冲突。
- Discourse 容器在
/var/discourse/containers/app.yml:
expose:
- "80" # 仅在容器网络内暴露,不做宿主端口映射
docker_args:
- "--network=web"
然后重建:
cd /var/discourse && ./launcher rebuild app- NPM 的 docker-compose:把
services:的服务名不要叫app,避免与 Discourse 默认容器名冲突;例如:
services:
npm-proxy:
container_name: npm
...
networks: [web]
networks:
web:
external: true- NPM 的 Proxy Host → Forward Hostname 填:
app,端口80,Schemehttp(不要再填app或容器 IP)。
6. 验证(两端各测一次)
# 公网侧:应以 200 结束(中途不应在 http↔https 来回跳)
curl -I -L https://abc.com
# NPM 容器里直连上游:应返回 Discourse 头(如 x-discourse-route)
docker exec -it npm curl -I http://app
常见坑位对照表
- 在 Proxy Host 的 Advanced 里写了 301/重写 → 可能与 force_https / Redirect Host 叠加,触发循环。
- 在 NPM 高级 自定义Nginx配置里自加 CSP → 与 Discourse 的 CSP 冲突,导致前端资源被拦,页面空白或转圈。
- Docker 内部 DNS 名称冲突(NPM 的 service 叫
app,Discourse 默认容器也叫app)→ 反代偶尔打到 NPM 自己。








