Does anyone have experience with hosing Discourse behind a Varnish instance? I use it for load balancing.
Which cookies do I need to whitelist (ie. enable to affect the page) when using Varnish?
Does anyone have experience with hosing Discourse behind a Varnish instance? I use it for load balancing.
Which cookies do I need to whitelist (ie. enable to affect the page) when using Varnish?
I have it working very well - as far as I can see Discourse behaves well towards Varnish and you can aggressively cache everything under the /assets directory.
backend discourse {
.host = "x.x.x.x";
.port = "81";
}
sub vcl_recv {
if (req.http.host == "forum.myhost.org.uk") {
set req.backend = discourse;
}
if (req.http.host == "forum.myhost.org.uk") {
if (req.url ~ "^/assets") {
return(lookup);
} else {
return(pipe);
}
}
Obviously there is more in my varnish config, but that is the basic / cache specific bit. I proxy through Apache, so in the virtual host have something like this:
<LocationMatch "^/assets/.*$">
Header set Cache-Control "public, max-age = 3600"
</LocationMatch>
In my setup, the max-age is used to tell varnish to cache, though different cache headings can be used.
There might be a few other things that can be safely cached (comments anyone?) though the above seems to work great.
It takes load off Apache, on which I run mod_security so the stack is both fast and pretty secure
)
Enjoy…
I would strongly recommend going with a origin pull CDN for assets as opposed to caching locally, CDNs are so cheap anyway.
That makes a lot of sense, thanks 
Reviving this briefly. I’ve already got Varnish running on my web server, so including Discourse’s static assets in it has basically zero additional cost to me.
On the other hand, I’m running Discourse behind Nginx with Passenger; Nginx is quite good at serving static assets—in fact, under low-to-moderate load, it’s almost always faster than Varnish. Varnish wins as load begins to ramp, though.
Right now (since my Discourse forum is LAN-only and really just for me to play with) I’ve got a statement in vcl_recv to just pass all traffic with my Discourse URL in it, but will it be problematic to enable it? @richp10, have you noticed any cookies placed that you need to strip?
I’ve gone ahead and turned on Varnish caching for my assets directory, using a slightly modified version of @richp10’s config:
# Cache only the static assets in Discourse's "assets" dir and pass everything else
if (req.http.host ~"discourse.bigdinosaur.org") {
if (!(req.url ~ "^/assets/")) {
return (pass);
}
}
This is a hell of a lot more convenient for me than dealing with a CDN, since I’m already using Varnish on the web server. Plus, there’s quite a bit of stuff in there; keeping the static assets in Varnish will ensure that they’re accessed from RAM instead of having to push IO down onto the disk.
I’m not anticipating a massive performance increase or anything, but it seems like just a smart thing to do.
Thanks! I needed this.
Maybe you can do a little “how to” tutorial for this plz?
Thanks!
I’ve changed my discourse varnish config since 2013. Looks like this now:
sub vcl_recv {
...
# Cache only the static assets and pass everything else
if (req.http.host ~"discourse.bigdinosaur.org") {
if (req.url ~ "^/uploads/" ) {
return (lookup);
}
elseif (req.url ~ "^/assets/") {
return (lookup);
}
elseif (req.url ~ "^/user_avatar/") {
return (lookup);
}
else {
return (pass);
}
}
...
}
sub vcl_pass {
set bereq.http.connection = "close";
# Fix broken behavior showing tons of requests from 127.0.0.1 with Discourse
if (req.http.X-Forwarded-For) {
set bereq.http.X-Forwarded-For = req.http.X-Forwarded-For;
} else {
set bereq.http.X-Forwarded-For = regsub(client.ip, ":.*", "");
}
}
Note also this is for Varnish 3. I’ve been putting off the migration to Varnish 4 because the VCL syntax changes and I haven’t put in the time to sit down and figure out how to translate my config.
Upgraded Varnish to V4, bringing with it some subtle but important VCL syntax changes. My Discourse block now looks like this, but it’s working only inconsistently:
# Cache only the static assets in Discourse's' "assets" dir and pass everything else
if (req.http.host ~"discourse.bigdinosaur.org") {
if (req.url ~ "^/uploads/" ) {
return (hash);
}
elseif (req.url ~ "^/assets/") {
return (hash);
}
elseif (req.url ~ "^/user_avatar/") {
return (hash);
}
else {
return (pipe);
}
}
(lol hash pipe)
I’m seeing weirdly inconsistent cache hits and I have absolutely no clue why. Some objects that match the regexes above (like user avatars) are being cached, and some others (like…other user avatars) aren’t.
Haven’t really had the time yet to sit down and try to figure out what might be wrong or misconfigured, since switching over to varnish v4 meant putting out a bunch of other fires, but I’ll poke at it tomorrow, maybe.
Quick update on this a year later: this is the Varnish 4.1/5 Discourse config I’ve been using that appears to work without any issues:
if (req.http.host ~"discourse.bigdinosaur.org") {
if (!(req.url ~ "(^/uploads/|^/assets/|^/user_avatar/)" )) {
return (pass);
}
}
Could probably also tweak it a bit, since it’s ignoring and not caching some emoji (specifically emojii with query strings on the end of their URLs) and a couple of other things (scripts, css). But it works!
edit - this is in sub vcl_recv, obviously.
这里的人似乎在使用 Varnish 加一个额外的 nginx。
这个额外的 nginx 部分似乎没有必要,而且 Discourse 在其容器中已经使用了 nginx。
有没有办法让 Varnish 直接连接到容器,而不需要额外的 nginx 或 Apache?
好的,我搞定了,问了个蠢问题。
而且移除其他代理后,加载速度会大幅提升。
另外,我使用了 @Lee_Ars 的缓存配置,但出现了一些奇怪的行为,比如某些帖子根本无法显示,所以目前所有请求都设置为返回(pass)。@Lee_Ars,你的缓存配置有没有遇到过什么奇怪的问题?
@Lee_Ars Varnish 6.x 有新的更新吗?谢谢。
我可以使用第二个 VPS 来运行 Varnish 吗?作为小型 Discourse 的低成本 CDN?
哈哈,四年后我可以给你更新一下!我仍然在使用自托管的 Discourse,但不再使用 Varnish。部分原因是,我已经将 Discourse 迁移到了自己的主机上,不再需要对其进行反向代理,另一部分原因是,最终 Varnish 的 RAM 缓存为静态资源提供的任何性能优势,都远远抵不上管理 Varnish 的复杂性。
如果这是你的目标,Cloudflare 的免费套餐很可能能以零成本满足你的需求。