Last active
December 27, 2022 02:56
-
-
Save matthewjackowski/062be03b41a68edbadfc to your computer and use it in GitHub Desktop.
Varnish 4 VCL configuration for WordPress. Also allows purging
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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?