Created
November 23, 2017 16:49
-
-
Save rjdp/39c74a5a6784a04322f3431a1120b926 to your computer and use it in GitHub Desktop.
Fairly robust VCL for django sites, can be used with some changes depending on the web App
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
# | |
# This is an example VCL file for Varnish. | |
# | |
# It does not do anything by default, delegating control to the | |
# builtin VCL. The builtin VCL is called when there is no explicit | |
# return statement. | |
# | |
# See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/ | |
# and https://www.varnish-cache.org/trac/wiki/VCLExamples for more examples. | |
# Marker to tell the VCL compiler that this VCL has been adapted to the | |
# new 4.0 format. | |
vcl 4.0; | |
import std; | |
# import digest; | |
# import directors; | |
backend default { | |
.host = "127.0.0.1"; | |
.port = "8080"; | |
.probe = { | |
#.url = "/"; # short easy way (GET /) | |
# We prefer to only do a HEAD / | |
.request = | |
"HEAD / HTTP/1.1" | |
"Host: www.example.com" | |
"Connection: close" | |
"User-Agent: Varnish Health Probe"; | |
.interval = 5s; # check the health of each backend every 5 seconds | |
.timeout = 1s; # timing out after 1 second. | |
.window = 5; # If 3 out of the last 5 polls succeeded the backend is considered healthy, otherwise it will be marked as sick | |
.threshold = 3; | |
} | |
.first_byte_timeout = 300s; # How long to wait before we receive a first byte from our backend? | |
.connect_timeout = 5s; # How long to wait for a backend connection? | |
.between_bytes_timeout = 2s; # How long to wait between bytes received from our backend? | |
} | |
backend examplemedia { | |
.host = "example.s3.amazonaws.com"; | |
.port = "80"; | |
.probe = { | |
#.url = "/"; # short easy way (GET /) | |
# We prefer to only do a HEAD / | |
.request = | |
"HEAD /DoNotDelete.txt HTTP/1.1" | |
"Connection: close" | |
"User-Agent: Varnish Health Probe"; | |
.interval = 5s; # check the health of each backend every 5 seconds | |
.timeout = 1s; # timing out after 1 second. | |
.window = 5; # If 3 out of the last 5 polls succeeded the backend is considered healthy, otherwise it will be marked as sick | |
.threshold = 3; | |
} | |
.first_byte_timeout = 300s; # How long to wait before we receive a first byte from our backend? | |
.connect_timeout = 5s; # How long to wait for a backend connection? | |
.between_bytes_timeout = 2s; # How long to wait between bytes received from our backend? | |
} | |
sub vcl_recv { | |
# Happens before we check if we have this in cache already. | |
# | |
# Typically you clean up the request here, removing cookies you don't need, | |
# rewriting the request, etc. | |
# non-www to www redirection | |
if (req.http.host ~ "^example.com") { | |
return (synth (750, "")); | |
} | |
if (req.url ~ "^/media/") { | |
set req.backend_hint = examplemedia; | |
} | |
if (req.url ~ "^/netdata") { | |
if (req.url == "/netdata") { | |
return (synth(301, "/netdata/")); | |
} | |
return(pass); | |
} | |
if (req.url ~ "^/static" || req.url ~ "^/media" || (req.http.cookie !~ "sessionid" && req.http.cookie !~ "csrftoken")) { | |
unset req.http.Cookie; | |
} | |
if (req.http.upgrade ~ "(?i)websocket") { | |
return (pipe); | |
} | |
if (req.http.Accept-Encoding) { | |
if (req.http.Accept-Encoding ~ "gzip") { | |
set req.http.Accept-Encoding = "gzip"; | |
} elsif (req.http.Accept-Encoding ~ "deflate") { | |
set req.http.Accept-Encoding = "deflate"; | |
} else { | |
# unkown algorithm | |
unset req.http.Accept-Encoding; | |
} | |
} | |
# Are there cookies left with only spaces or that are empty? | |
if (req.http.cookie ~ "^\s*$") { | |
unset req.http.cookie; | |
} | |
# Remove port | |
# set req.http.Host = regsub(req.http.Host, ":[0-9]+", ""); | |
# Sort query parmas in URL have single cahe obj for sematically identical URL | |
set req.url = std.querysort(req.url); | |
# Remove ending question mark | |
if (req.url ~ "\?$") { | |
set req.url = regsub(req.url, "\?$", ""); | |
} | |
} | |
sub vcl_backend_response { | |
# Happens after we have read the response headers from the backend. | |
# | |
# Here you clean the response headers, removing silly Set-Cookie headers | |
# and other mistakes your backend does. | |
# assuming all static file are being served from /static | |
if (bereq.url ~ "^/static" || bereq.url ~ "^/media" || (beresp.http.set-cookie !~ "sessionid" && beresp.http.set-cookie !~ "csrftoken")) { | |
set beresp.grace = 1d; | |
if (bereq.url ~ "^/static" || bereq.url ~ "^/media") { | |
set beresp.ttl = 10w; | |
} | |
unset beresp.http.set-cookie; | |
return (deliver); | |
} | |
} | |
sub vcl_hit { | |
if (obj.ttl >= 0s) { | |
// A pure unadulterated hit, deliver it | |
return (deliver); | |
} | |
if (!std.healthy(req.backend_hint) && (obj.ttl + obj.grace > 0s)) { | |
// Object is in grace, deliver it | |
// Automatically triggers a background fetch | |
return (deliver); | |
} | |
// fetch & deliver once we get the result | |
return (miss); | |
} | |
sub vcl_deliver { | |
# Happens when we have all the pieces we need, and are about to send the | |
# response to the client. | |
# | |
# You can do accounting or modifying the final object here. | |
set resp.http.X-Hits = obj.hits; | |
if (obj.hits > 0) { | |
set resp.http.X-Cache = "HIT"; | |
} else { | |
set resp.http.X-Cache = "MISS"; | |
} | |
} | |
sub vcl_synth { | |
if (resp.status == 301 || resp.status == 302) { | |
set resp.http.location = resp.reason; | |
set resp.reason = "Moved"; | |
return (deliver); | |
} | |
if (resp.status == 750) { | |
set resp.status = 301; | |
set resp.http.Location = "http://www.example.com" + req.url; | |
return(deliver); | |
} | |
} | |
sub vcl_pipe { | |
if (req.http.upgrade) { | |
set bereq.http.upgrade = req.http.upgrade; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment