For the RaspberryPI Kubernetes deployment experiment that’s serving this page, I wanted to use Varnish for a simple static asset cache. I’m not sure why I decided to go down this path, because this site isn’t exactly high traffic, but ¯\_(ツ)_/¯.
After about 30 seconds of looking around I couldn’t find a pre-built ARM64 docker image for Varnish… so I built one.
Building the image
This was about as much as creating a image repository on DockerHub, cloning this, and running:
$ docker buildx build --platform linux/arm64 . -t zackkitzmiller/varnish-arm:alpine --push
The image is now here on DockerHub.
update: Here’s the Elixir configuration file with websocket support
vcl 4.0;
import directors;
import std;
backend z19rpw {
.host = "z19rpw-service";
.port = "80";
}
sub vcl_recv {
if (req.http.upgrade ~ "(?i)websocket") {
return (pipe);
}
# normalize the port for testing/staging
set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
std.log(req.http.Host);
# pass on the real IP address here as X-Forwarded-For
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
if (req.http.Host ~ "z19r.pw") {
std.log("setting backend to z19rpw");
set req.backend_hint = z19rpw;
}
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
if (req.url == "/") {
std.log("attempting to cache home");
unset req.http.Cookie;
return (hash);
}
if (req.url ~ "\.(png|jpg|jpeg|css|js)") {
std.log("processing for z19r assets");
unset req.http.Cookie;
return (hash);
}
std.log("not an asset request");
return (pass);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
return (deliver);
}
sub vcl_backend_response {
if (bereq.url ~ "\.(png|jpg|jpeg|css|js)" || bereq.url == "/") {
unset beresp.http.set-cookie;
}
if (bereq.url ~ "^/$") {
# Software pages are purged explicitly, so cache them for 48h
set beresp.http.Cache-Control = "max-age=3600";
set beresp.ttl = 1h;
}
return (deliver);
}
sub vcl_pipe {
if (req.http.upgrade) {
set bereq.http.upgrade = req.http.upgrade;
set bereq.http.connection = req.http.connection;
}
return (pipe);
}