Varnish VCL Configuration on Ubuntu 24.04
Complete example VCL with common patterns
vcl 4.1;
import std;
# Backend servers
backend web1 {
.host = "192.168.1.10";
.port = "8080";
.probe = {
.url = "/health";
.timeout = 5s;
.interval = 10s;
.window = 5;
.threshold = 3;
}
}
backend web2 {
.host = "192.168.1.11";
.port = "8080";
.probe = {
.url = "/health";
.timeout = 5s;
.interval = 10s;
}
}
# Load balancing director
sub vcl_init {
new lb = directors.round_robin();
lb.add_backend(web1);
lb.add_backend(web2);
}
sub vcl_recv {
# Use load balancer
set req.backend_hint = lb.backend();
# Normalize Accept-Encoding
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
unset req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "br") {
set req.http.Accept-Encoding = "br";
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} else {
unset req.http.Accept-Encoding;
}
}
# Don't cache POST/PUT/DELETE
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# Don't cache authenticated requests
if (req.http.Authorization) {
return (pass);
}
# Strip session cookies for static files
if (req.url ~ "\.(css|js|png|jpg|gif|ico|svg|woff2?)$") {
unset req.http.Cookie;
return (hash);
}
}
sub vcl_hash {
hash_data(req.url);
hash_data(req.http.host);
}
sub vcl_backend_response {
# Grace: serve stale if backend is slow
set beresp.grace = 30s;
# Cache static files
if (bereq.url ~ "\.(css|js|png|jpg|gif|ico|woff2?)$") {
unset beresp.http.Set-Cookie;
set beresp.ttl = 7d;
}
# Don't cache server errors
if (beresp.status >= 500) {
set beresp.ttl = 0s;
set beresp.uncacheable = true;
return (deliver);
}
}
sub vcl_deliver {
# Add cache hit/miss header for debugging
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
set resp.http.X-Cache-Hits = obj.hits;
} else {
set resp.http.X-Cache = "MISS";
}
unset resp.http.X-Varnish;
unset resp.http.Via;
}
Purge cached objects
varnishadm "ban req.http.host == example.com && req.url ~ /blog"
# Or with HTTP PURGE method (add to vcl_recv):
if (req.method == "PURGE") {
if (!client.ip ~ purge_acl) {
return (synth(405, "Not allowed"));
}
return (purge);
}