You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

借助Varnish与Hitch代理部署Discourse论坛及多站点的问题排查

问题解决:Discourse在Varnish+Hitch架构下的资源加载与登录异常

问题根源分析

  • 资源(Logo/附件)加载失败:Discourse未正确识别前端的HTTPS协议,生成的资源链接为http://,被浏览器的混合内容安全策略拦截。
  • 强制HTTPS后无法登录:Discourse会话Cookie未标记Secure属性,且X-Forwarded-Proto头未正确传递,导致登录请求出现重定向循环或Cookie无法在HTTPS环境下生效。

解决方案

1. 修正Varnish的default.vcl配置

原配置中对Discourse请求直接使用pipe会跳过后续头处理逻辑,导致X-Forwarded-Proto无法传递给后端,需调整如下:

vcl 4.1;
import std;

backend default {
    .host = "192.168.1.103";
    .port = "8080";
}
backend discourse {
    .host = "192.168.1.103";
    .port = "8081";
}

sub vcl_recv {
    # 优先处理HTTP转HTTPS重定向,所有非443端口请求强制跳转
    if (std.port(server.ip) != 443) {
        set req.http.location = "https://" + req.http.host + req.url;
        return(synth(301));
    }

    # 设置X-Forwarded-Proto头,告知后端当前使用HTTPS协议
    if (!req.http.X-Forwarded-Proto) {
        set req.http.X-Forwarded-Proto = "https";
    }

    # 路由到对应后端,Discourse使用pass而非pipe以保留头处理逻辑
    if (req.http.host == "discourse.example.com") {
        set req.backend_hint = discourse;
        return (pass);
    } else {
        set req.backend_hint = default;
    }
}

sub vcl_backend_response {
    # 强制给Discourse的Cookie添加Secure属性,确保HTTPS环境下正常传输
    if (bereq.http.host == "discourse.example.com") {
        set beresp.http.Set-Cookie = regsuball(beresp.http.Set-Cookie, "(; )?(Secure)?", "; Secure");
    }
}

sub vcl_synth {
    if (resp.status == 301 || resp.status == 302) {
        set resp.http.location = req.http.location;
        return (deliver);
    }
}

2. 配置Discourse识别反向代理的HTTPS

修改Discourse的app.yml,添加反向代理信任配置,让Discourse正确识别前端的HTTPS环境:

expose: 
- "8081:80" # http
# - "443:443" # https

## 添加反向代理相关环境变量
env:
  DISCOURSE_FORCE_HTTPS: true
  DISCOURSE_TRUSTED_PROXIES: 192.168.1.103 # 填写Varnish服务器的IP地址
  DISCOURSE_X_FORWARDED_PROTO: https

## Uncomment these two lines if you wish to add Lets Encrypt (https)
# - "templates/web.ssl.template.yml"
# - "templates/web.letsencrypt.ssl.template.yml"
## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
# LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

3. 验证Hitch配置

确保Hitch将解密后的HTTPS请求转发到Varnish的监听端口(默认6081),检查Hitch配置文件中是否存在:

backend = "[127.0.0.1]:6081"

4. 重启服务使配置生效

  • 重启Varnish:systemctl restart varnish
  • 重建并重启Discourse:cd /var/discourse && ./launcher rebuild app
  • 重启Hitch:systemctl restart hitch

内容的提问来源于stack exchange,提问作者Umair Suraj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:27:05