Caddy, Varnish, WordPress, Ubuntu = Fun

Architecture:

What’s the point of all this?

Why are there so many layers?

Why Caddy?

The primary goal of this architecture is to massively and immediately improve any given WordPress site with a quick and easy upgrade to HTTP/2, always-on HTTPS, and robust caching and compression middleware. To that end, we can envision a stack that looks something like:

Varnish enables caching and compression of static assets as well as dynamic content and is the best in its class, so let’s plug that in. This leaves us wanting for implementations of the following components:

SSL termination and certificate management

Request sanitization and XSS attack mitigation*

Request and error logging

IP-based whitelisting and rate-limiting

URL rewriting (in request headers)

URL canonicalization (in response bodies)

Static asset serving

Hand-off to Varnish via reverse proxy

Hand-off to PHP-FPM via FastCGI

Caddy does (*almost) all of these things right out of the box. It makes the “happy path” very happy. And although HAProxy might be better at the edge, and NGINX might have more features, Caddy is a nice fit for this use-case. Performance is still an open question, but so far it’s held up under load quite capably for me.

This should (hopefully) illustrate why we need so many different layers. It may help to think of the left side of the stack as content distrbution, and the right side of the stack as content origination. Keeping these two halves separate makes it easy to scale when you’re ready by letting you swap in a content distribution network (CDN)—which is essentially caching and compression as a service with anycast and SSL termination—while keeping the same origin:

VCL:

Change /etc/varnish/default.vcl like so:

# Marker to tell the VCL compiler that this VCL has been adapted to the
# new 4.0 format.
vcl 4.0;
# Default backend definition. Set this to point to your content server.
backend default {
.host = "localhost";
.port = "8888";
}

WordPress:

Most WordPress optimization guides suggest unsetting cache control headers such as Cache-Control, ETag, Last-Modified, Expires, etc. Instead, we’re going to set them and let Varnish serve posts, pages, and attachments as slowly-changing dynamic content. Yes, you read that correctly: your WordPress site is now a glorified static site generator!

Change your WordPress and Site Addresses to https:// in wp-config.php, or by using the wp-cli tool.