Varnish Tutorial Part 1: HTTP Caching With Varnish
In this tutorial we'll set up a HTTP cache with Varnish.
This is the second part to my Varnish tutorial series. In this article we'll take a look at clearing the cache.
In the previous tutorial, we ended up with the following default.vcl
:
vcl 4.1;
backend default {
.host = "beakerstudio-splash.s3-website.us-east-2.amazonaws.com:80";
}
sub vcl_recv {
set req.http.host = "beakerstudio-splash.s3-website.us-east-2.amazonaws.com";
}
After starting Varnish, we can then verify it is working with curl:
curl -v http://localhost:8080/
The output should look something like this:
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/html
< Server: AmazonS3
< Content-Length: 1875
< X-Varnish: 9 3
< Age: 11
< Via: 1.1 varnish (Varnish/7.0)
< Accept-Ranges: bytes
< Connection: keep-alive
<
[HTML redacted]
With our current configuration, we have to completely restart Varnish in order to clear the cache. Let's change that by ammending default.vcl
:
vcl 4.1;
backend default {
.host = "beakerstudio-splash.s3-website.us-east-2.amazonaws.com:80";
}
sub vcl_recv {
set req.http.host = "beakerstudio-splash.s3-website.us-east-2.amazonaws.com";
if (req.method == "PURGE") {
return (purge);
}
}
As you can see, we've added a conditional to sub vcl_recv
. This checks if the HTTP method is PURGE
, and if so it removes the requested page from cache. Restart Varnish, then test with curl:
curl -vX PURGE http://localhost:8080/
The output should show header HTTP/1.1 200 Purged
:
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> PURGE / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 Purged
< Server: Varnish
< X-Varnish: 32772
< Content-Type: text/html; charset=utf-8
< Retry-After: 5
< Content-Length: 240
< Connection: keep-alive
<
[HTML redacted]
The next GET
request should return an Age: 0
header to indicate it is not a cached response.
This purges the cache for the requested page. So in order to clear http://localhost:8080/foo/
for example you would run curl -vX PURGE http://localhost:8080/foo/
.
The above is great for selectively clearing pages from Varnish, but what if we want to clear all pages? Let's revisit default.vcl
:
vcl 4.1;
backend default {
.host = "beakerstudio-splash.s3-website.us-east-2.amazonaws.com:80";
}
sub vcl_recv {
set req.http.host = "beakerstudio-splash.s3-website.us-east-2.amazonaws.com";
if (req.method == "PURGE") {
ban("req.http.host ~ .*");
return (synth(200, "Full cache cleared"));
}
}
Here we have replaced return (purge);
with a call to ban
with a pattern that matches all pages on the configured host, and then send a custom HTTP 200 response.
Once again we use curl -vX PURGE http://localhost:8080/
to clear the cache. This time tthe output should show header HTTP/1.1 200 Full cache cleared
:
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> PURGE / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 Full cache cleared
< Server: Varnish
< X-Varnish: 32772
< Content-Type: text/html; charset=utf-8
< Retry-After: 5
< Content-Length: 276
< Connection: keep-alive
<
[HTML redacted]
In this tutorial we looked at two different ways to clear Varnish cache. There's one major omission you might have noticed, which is that we don't authenticate PURGE requests. This means anyone may clear our cache, which could lead to performance issues and DoS attacks! In the next article we will cover securing Varnish against PURGE attacks.
Published:
In this tutorial we'll set up a HTTP cache with Varnish.
These are the open-source technologies that I'm most thankful for in 2021.
File version control is important whether you are working with simple Word documents, design files, or source code. Good version control acts as both a backup solution and an annotated log of changes made to the document over time. As a developer, I already use Git extensively for version control, so I wanted to see if I could use Git for Sketch as well.