Varnish image with flagship module built-in
381
Maintained by:
The flagship developer team
Where to get help:
[email protected]
Where to file issues:
https://github.com/flagship-io/flagship-varnish-module/issues
Dockerfile linksVarnish is an HTTP accelerator designed for content-heavy dynamic web sites as well as APIs. In contrast to other web accelerators, such as Squid, which began life as a client-side cache, or Apache and nginx, which are primarily origin servers, Varnish was designed as an HTTP accelerator. Varnish is focused exclusively on HTTP, unlike other proxy servers that often support FTP, SMTP and other network protocols.
Create a default.vcl file
# specify the VCL syntax version to use
vcl 4.0;
import std;
import cookie;
import blob;
import header;
# import vmod_flagship to perfom experimentation and feature flag in varnish
import flagship;
# we won't use any static backend, but Varnish still need a default one
backend default none;
# initiate the flagship instance
sub vcl_init {
flagship.init(envID=std.getenv("FS_ENV_ID"), apiKey=std.getenv("FS_API_KEY"), pollingInterval=std.integer(std.getenv("FS_POLLING_INTERVAL"), 10), logLevel=std.getenv("FS_LOG_LEVEL"), trackingEnabled=std.integer(std.getenv("FS_TRACKING_ENABLED"), 0));
}
sub vcl_recv {
unset req.http.x-cache;
# the visitor ID
set req.http.X-VISITOR-ID = "" + req.xid;
# initialize the visitor context
set req.http.X-VISITOR-CONTEXT = "";
# fillout the chrome device as context for example
if (req.http.User-Agent ~ "Chrome") {
set req.http.X-VISITOR-CONTEXT = "device:chrome";
} else if (req.http.User-Agent ~ "Mozilla.*Firefox*") {
set req.http.X-VISITOR-CONTEXT = "device:firefox";
} else {
set req.http.X-VISITOR-CONTEXT = "device:edge";
}
if (req.url ~ "^/") {
return (synth(200, "Flagship"));
}
return(hash);
}
sub vcl_hash {
# this is where we should call flagship code to compute flag values
set req.http.X-FS-FLAGVALUES = flagship.compute_flags(req.http.X-VISITOR-ID, req.http.X-VISITOR-CONTEXT);
# you can also call flagship to get flag
set req.http.X-FS-FLAGSTRING = flagship.get_flag_string(req.http.X-VISITOR-ID, req.http.X-VISITOR-CONTEXT, "color", "white", 1);
# you can also call flagship to get flag
set req.http.X-FS-FLAGBOOL = flagship.get_flag_bool(req.http.X-VISITOR-ID, req.http.X-VISITOR-CONTEXT, "IsVIP", 0, 1);
# you can also call flagship to get flag
set req.http.X-FS-FLAGNUMBER = flagship.get_flag_number(req.http.X-VISITOR-ID, req.http.X-VISITOR-CONTEXT, "price", 9.99, 1);
# the builtin.vcl will take care of also varying cache on those flag values
hash_data(req.http.X-FS-FLAGVALUES);
}
# Log cache miss, hit, pass, pipe & synth in header
sub vcl_hit {
set req.http.x-cache = "hit";
}
sub vcl_miss {
set req.http.x-cache = "miss";
}
sub vcl_pass {
set req.http.x-cache = "pass";
}
sub vcl_pipe {
set req.http.x-cache = "pipe uncacheable";
}
sub vcl_synth {
set resp.http.Content-Type = "text/html; charset=utf-8";
set resp.http.Retry-After = "5";
set resp.body = {"<!DOCTYPE html>
<html>
<head>
<title>"} + resp.reason + {"</title>
</head>
<body>
<h1>"} + resp.reason + {"</h1>
<p>Visitor ID: "} + req.http.X-VISITOR-ID + {"</p>
<p>Visitor context: "} + req.http.X-VISITOR-CONTEXT + {"</p>
<p>Flagship getAllFlags: "} + req.http.X-FS-FLAGVALUES + {"</p>
</body>
</html>
"};
return (deliver);
}
# This function is used when a request is sent by our backend
sub vcl_backend_response {
# If we find our layout cookie we copy it to a header and then we remove it so we can cache the page
# Later after we deliver the page from cache we set the cookie from the header and then remove that header
if ( beresp.http.Set-Cookie ) {
set beresp.http.fs-cookie = beresp.http.Set-Cookie;
unset beresp.http.Set-Cookie;
}
}
sub vcl_deliver {
if(resp.http.fs-cookie){
set resp.http.Set-Cookie = resp.http.fs-cookie;
unset resp.http.fs-cookie;
}
# Add flagship values to cookie if set
if (req.http.X-FS-FLAGVALUES) {
header.append(resp.http.Set-Cookie,"FS-FLAGVALUES=" + blob.transcode(encoded=req.http.X-FS-FLAGVALUES, encoding=URL) + "; Domain=localhost");
}
if (obj.uncacheable) {
set resp.http.x-cache = req.http.x-cache + " uncacheable" ;
} else {
set resp.http.x-cache = req.http.x-cache + " cached" ;
}
}
Then run:
# we need the configuration file at /etc/varnish/default.vcl,
# our workdir has to be mounted as tmpfs to avoid disk I/O,
# and we'll use port 8080 to talk to our container (internally listening on 80)
docker run -it -p 8080:80 -t --name varnish-standalone \
-v /path/to/default.vcl:/etc/varnish/default.vcl:ro \
--tmpfs /var/lib/varnish/varnishd:exec \
-e "FS_ENV_ID=ENV_ID" \
-e "FS_API_KEY=API_KEY" \
-e "FS_POLLING_INTERVAL=50" \
-e "FS_LOG_LEVEL=debug" \
-e "FS_TRACKING_ENABLED=0" \
flagshipio/varnish:7.2
From there, you can visit localhost:8080 in your browser and see the example homepage.
The images all ship with varnishreload which allows you to easily update the running configuration without restarting the container (and therefore losing your cache). At its most basic, you just need this:
# update the default.vcl in your container
docker cp new_default.vcl running_container:/etc/varnish/default.vcl
# run varnishreload
docker exec running_container varnishreload
Note that varnishreload also supports reloading other files (it doesn't have to be default.vcl), labels (l), and garbage collection of old labeles (-m) among others. To know more, run
docker run varnish varnishreload -h
Content type
Image
Digest
sha256:0556564c4…
Size
207.9 MB
Last updated
almost 4 years ago
docker pull flagshipio/varnish:7.2