# A heavily customized VCL to support WordPress | |
# Some items of note: | |
# Supports https | |
# Supports admin cookies for wp-admin | |
# Caches everything | |
# Support for custom error html page | |
vcl 4.0; | |
import directors; | |
import std; | |
# Assumed 'wordpress' host, this can be docker servicename | |
backend default { | |
.host = "wordpress"; | |
.port = "80"; | |
} | |
acl purge { | |
"localhost"; | |
"127.0.0.1"; | |
} | |
sub vcl_recv { | |
# Only a single backend | |
set req.backend_hint= default; | |
# Setting http headers for backend | |
set req.http.X-Forwarded-For = client.ip; | |
set req.http.X-Forwarded-Proto = "https"; | |
# Unset headers that might cause us to cache duplicate infos | |
unset req.http.Accept-Language; | |
unset req.http.User-Agent; | |
# The purge...no idea if this works | |
if (req.method == "PURGE") { | |
if (!client.ip ~ purge) { | |
return(synth(405,"Not allowed.")); | |
} | |
ban("req.url ~ /"); | |
return (purge); | |
} | |
if ( std.port(server.ip) == 6080) { | |
set req.http.x-redir = "https://" + req.http.host + req.url; | |
return (synth(750, "Moved permanently")); | |
} | |
# drop cookies and params from static assets | |
if (req.url ~ "\.(gif|jpg|jpeg|swf|ttf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") { | |
unset req.http.cookie; | |
set req.url = regsub(req.url, "\?.*$", ""); | |
} | |
# drop tracking params | |
if (req.url ~ "\?(utm_(campaign|medium|source|term)|adParams|client|cx|eid|fbid|feed|ref(id|src)?|v(er|iew))=") { | |
set req.url = regsub(req.url, "\?.*$", ""); | |
} | |
# pass wp-admin urls | |
if (req.url ~ "(wp-login|wp-admin)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") { | |
return (pass); | |
} | |
# pass wp-admin cookies | |
if (req.http.cookie) { | |
if (req.http.cookie ~ "(wordpress_|wp-settings-)") { | |
return(pass); | |
} else { | |
unset req.http.cookie; | |
} | |
} | |
} | |
sub vcl_backend_response { | |
# retry a few times if backend is down | |
if (beresp.status == 503 && bereq.retries < 3 ) { | |
return(retry); | |
} | |
if (bereq.http.Cookie ~ "(UserID|_session)") { | |
# if we get a session cookie...caching is a no-go | |
set beresp.http.X-Cacheable = "NO:Got Session"; | |
set beresp.uncacheable = true; | |
return (deliver); | |
} elsif (beresp.ttl <= 0s) { | |
# Varnish determined the object was not cacheable | |
set beresp.http.X-Cacheable = "NO:Not Cacheable"; | |
} elsif (beresp.http.set-cookie) { | |
# You don't wish to cache content for logged in users | |
set beresp.http.X-Cacheable = "NO:Set-Cookie"; | |
set beresp.uncacheable = true; | |
return (deliver); | |
} elsif (beresp.http.Cache-Control ~ "private") { | |
# You are respecting the Cache-Control=private header from the backend | |
set beresp.http.X-Cacheable = "NO:Cache-Control=private"; | |
set beresp.uncacheable = true; | |
return (deliver); | |
} else { | |
# Varnish determined the object was cacheable | |
set beresp.http.X-Cacheable = "YES"; | |
# Remove Expires from backend, it's not long enough | |
unset beresp.http.expires; | |
# Set the clients TTL on this object | |
set beresp.http.cache-control = "max-age=900"; | |
# Set how long Varnish will keep it | |
set beresp.ttl = 1w; | |
# marker for vcl_deliver to reset Age: | |
set beresp.http.magicmarker = "1"; | |
} | |
# unset cookies from backendresponse | |
if (!(bereq.url ~ "(wp-login|wp-admin)")) { | |
set beresp.http.X-UnsetCookies = "TRUE"; | |
unset beresp.http.set-cookie; | |
set beresp.ttl = 1h; | |
} | |
# long ttl for assets | |
if (bereq.url ~ "\.(gif|jpg|jpeg|swf|ttf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") { | |
set beresp.ttl = 365d; | |
} | |
set beresp.grace = 1w; | |
} | |
sub vcl_hash { | |
if ( req.http.X-Forwarded-Proto ) { | |
hash_data( req.http.X-Forwarded-Proto ); | |
} | |
} | |
sub vcl_backend_error { | |
# display custom error page if backend down | |
if (beresp.status == 503 && bereq.retries == 3) { | |
synthetic(std.fileread("/etc/varnish/error503.html")); | |
return(deliver); | |
} | |
} | |
sub vcl_synth { | |
# redirect for http | |
if (resp.status == 750) { | |
set resp.status = 301; | |
set resp.http.Location = req.http.x-redir; | |
return(deliver); | |
} | |
# display custom error page if backend down | |
if (resp.status == 503) { | |
synthetic(std.fileread("/etc/varnish/error503.html")); | |
return(deliver); | |
} | |
} | |
sub vcl_deliver { | |
# oh noes backend is down | |
if (resp.status == 503) { | |
return(restart); | |
} | |
if (resp.http.magicmarker) { | |
# Remove the magic marker | |
unset resp.http.magicmarker; | |
# By definition we have a fresh object | |
set resp.http.age = "0"; | |
} | |
if (obj.hits > 0) { | |
set resp.http.X-Cache = "HIT"; | |
} else { | |
set resp.http.X-Cache = "MISS"; | |
} | |
set resp.http.Access-Control-Allow-Origin = "*"; | |
} | |
sub vcl_hit { | |
if (req.method == "PURGE") { | |
return(synth(200,"OK")); | |
} | |
} | |
sub vcl_miss { | |
if (req.method == "PURGE") { | |
return(synth(404,"Not cached")); | |
} | |
} |
This comment has been minimized.
This comment has been minimized.
@makmour I reduced the logic on that condition and also set an X-param to be able to see when it triggers. Seems to be ok for me on my local docker setup. Keep in mind that to enable https you have todo alot of tomfoolery in Wordpress too. |
This comment has been minimized.
This comment has been minimized.
It works great, thank you sir |
This comment has been minimized.
This comment has been minimized.
Hi, it works great with https. But not all my sites are https. I can not log in to my sites with http. How do I add a code for this to help you? |
This comment has been minimized.
This comment has been minimized.
Thanks for this! There's a surprising lack of good/up to date configs out there. I did run into small issue though: Have you noticed that Wordpress' Visual Editor doesn't load with this config? I disabled Varnish all together and the Visual Editor comes right back. I can't seem to figure it out. Any ideas? |
This comment has been minimized.
This comment has been minimized.
Hello, How can my overcome this problem? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@dockrize what should I do. Please tell me in detail. |
This comment has been minimized.
This comment has been minimized.
@matthewjackowski If you know, please answer me? |
This comment has been minimized.
This comment has been minimized.
So far this is excellent. I keep reading about issues people have ran into with CloudFlare and Varnish -- I'm still new to this stuff but so far it SEEMS to be working? Any thoughts, ideas? fixes if an issue? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@informdev thank you so much. My problem is resolved. |
This comment has been minimized.
This comment has been minimized.
It shows apache default page when i ran this vcl file. |
This comment has been minimized.
This comment has been minimized.
Tried all configurations I still have the same problem as Marco41... Please someone help us out. I noticed without varnish these URLs http://felipeferreira.net/wp-content/themes/bandana/css/editor-style.css?wp-mce-4607-20180123-tadv-4.6.7 Then with varnish ON, I no longer see those, and I see something trunked like: have been struginling with this problem for over 2 years now, I have tried
but did not work... |
This comment has been minimized.
This comment has been minimized.
Hey, @xoroz, I had the same problem with the WordPress visual editor, But adding the code snippet as the very first condition to evaluated in vcl_recv fixed it for me. Pasting the same code snippet here for reference.
Hope it helps. |
This comment has been minimized.
This comment has been minimized.
Why are u removing the User-Agent header from the request? |
This comment has been minimized.
This comment has been minimized.
Watch out for this booby trap! set resp.http.Access-Control-Allow-Origin = "*"; |
This comment has been minimized.
This comment has been minimized.
Hey there, could you point me in the right direction in order to make the WP backend work? I'm getting a redirect loop error. |
This comment has been minimized.
This comment has been minimized.
Hi! I would add this for certbot passthrough (for people using Let's Encrypt SSL/TLS):
|
This comment has been minimized.
This comment has been minimized.
Is that VCL compatible with the latest wordpress and woocommerce? |
This comment has been minimized.
This comment has been minimized.
I've just debugged this for a site I was working on: please replace the purge method there:
with
The purge is done with
otherwise the purge isn't actually conducted |
This comment has been minimized.
This comment has been minimized.
if you have a specific url to login
|
This comment has been minimized.
This comment has been minimized.
Thanks for this, this worked for me too |
This comment has been minimized.
This comment has been minimized.
Hi everyone! OP here, I had no idea so many people were using this as I have moved away from using Varnish for my Wordpress sites in favor of static publishing but am happy to maintain this config. |
This comment has been minimized.
This comment has been minimized.
Just to be clear, my original intent is to NOT to have the Wordpress BE work through Varnish. There is just so much to think about/can go wrong. Additionally I have security concerns around this because many Wordpress attacks target BE urls. |
This comment has been minimized.
This comment has been minimized.
Certainly there is no intent for this to be a "booby trap". The intent is to cache external assets that CORS would otherwise block. Unfortunately I'm not sure how to make this less "scary". Maybe put a url condition on it like this: |
This comment has been minimized.
This comment has been minimized.
Great comment! This is definitely a rather "opinionated" setting. |
This comment has been minimized.
This comment has been minimized.
For me this line stops WP's visual editor loading |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
Hello Matthewjackowski, this line creates an endless loop from https to http and back again. Ok i use varnish 5.2.1 , is the Code ok?
|
This comment has been minimized.
Hi!
There is something worng with
because it makes WP to fail loading the test cookie thus not permitting users to login into the Dashboard,