Newsletter
TechAnV Blog
Get updates on security engineering, Rust, eBPF, and DevSecOps. No spam, unsubscribe anytime.
Check your inbox and click the confirmation link to complete your subscription.
Running Varnish on Fly#
The goal: run Varnish in a Fly container as a caching proxy in front of another Fly application.
I ended up switching to Cloudflare for running a Varnish-style cache in front of my Fly application (purely to reduce the number of moving parts I needed to maintain), but I’m publishing my notes on how I got Varnish working here in case I need them in the future.
The Dockerfile#
Fly apps run Docker containers. Here’s the minimal Dockerfile that worked for me:
1FROM varnish2
3COPY default.vcl /etc/varnish/4
5USER varnish6
7ENTRYPOINT [ \8 "varnishd", "-F", \9 "-f", "/etc/varnish/default.vcl", \10 "-a", "http=:8000,HTTP", \11 "-s", "malloc,256M", \12 "-T", "none" \13]default.vcl#
The default.vcl file is the Varnish configuration file. Here’s the one I used:
1vcl 4.1;2
3backend default {4 .host = "my-underlying-app.fly.dev";5 .port = "80";6}7
8sub vcl_recv {9 unset req.http.x-cache;10}11
12sub vcl_hit {13 set req.http.x-cache = "hit";14}15
16sub vcl_miss {17 set req.http.x-cache = "miss";18}19
20sub vcl_pass {21 set req.http.x-cache = "pass";22}23
24sub vcl_pipe {25 set req.http.x-cache = "pipe uncacheable";26}27
28sub vcl_synth {29 set req.http.x-cache = "synth synth";30 set resp.http.x-cache = req.http.x-cache;31}32
33sub vcl_deliver {34 if (obj.uncacheable) {35 set req.http.x-cache = req.http.x-cache + " uncacheable" ;36 } else {37 set req.http.x-cache = req.http.x-cache + " cached" ;38 }39 set resp.http.x-cache = req.http.x-cache;40}fly.toml#
The Fly configuration file for the application:
1app = "my-varnish-app"2primary_region = "lax"3kill_signal = "SIGINT"4kill_timeout = "5s"5
6[[services]]7 internal_port = 80008 protocol = "tcp"9
10 [services.concurrency]11 hard_limit = 2512 soft_limit = 2013
14 [[services.ports]]15 handlers = ["http"]16 port = 8017
18 [[services.ports]]19 handlers = ["tls", "http"]20 port = 44321
22 [[services.tcp_checks]]23 interval = 1000024 timeout = 200025 grace_period = "10s"I’m using internal_port = 8000 here because I ran Varnish using -a "http=:8000,HTTP" in the ENTRYPOINT in the Dockerfile.
Deploying the application#
With all of the above files in a folder, the deploy command looks like this:
1flyctl deployThe result ends up running at https://my-varnish-app.fly.dev/, and will serve pages from the underlying app - only caching them if those pages include a cache-control: s-maxage=15 header or similar.
Further reading#
I pieced this together mainly with help from the information in this 4 year old forum thread, plus searching around for more recent Varnish configuration examples.