Varnish config for wordpress with ngx_pagespeed and wp-touch

This is the Varnish config I am using currently. It is working with wp-touch, pagespeed and wordpress and (bonus) deals with the pagespeed not allowing pages to cache. No time for pretty comments and explanations, here’s the code. I will answer questions, or come back and explain the code in comments – but it is pretty self explanatory.

backend default {
.host = "127.0.0.1";
.port = "80";
.first_byte_timeout = 300s;
}

sub generate_user_agent_based_key {
set req.http.default_ps_capability_list_for_large_screens = "LargeScreen.SkipUADependentOptimizations:";
set req.http.default_ps_capability_list_for_small_screens = "TinyScreen.SkipUADependentOptimizations:";

set req.http.PS-CapabilityList = req.http.default_ps_capability_list_for_large_screens;

# Lazyload
if (req.http.User-Agent ~ “(?i)Chrome/|Firefox/|MSIE |Safari”) {
set req.http.PS-CapabilityList = “ll,ii,dj:”;
}
# lazyload_images (ll), inline_images (ii), defer_javascript (dj), webp (jw) and lossless_webp (ws).
if (req.http.User-Agent ~
“(?i)Chrome/[2][3-9]+\.|Chrome/[[3-9][0-9]+\.|Chrome/[0-9]{3,}\.”) {
set req.http.PS-CapabilityList = “ll,ii,dj,jw,ws:”;
}
# odd ones
if (req.http.User-Agent ~ “(?i)Firefox/[1-2]\.|MSIE [5-8]\.|bot|Yahoo!|Ruby|RPT-HTTPClient|(Google \(\+https\:\/\/developers\.google\.com\/\+\/web\/snippet\/\))|Android|iPad|TouchPad|Silk-Accelerated|Kindle Fire”) {
set req.http.PS-CapabilityList = req.http.default_ps_capability_list_for_large_screens;
}
# mobile
if (req.http.User-Agent ~ “(?i)Mozilla.*Android.*Mobile*|iPhone|BlackBerry|Opera Mobi|Opera Mini|SymbianOS|UP.Browser|J-PHONE|Profile/MIDP|portalmmm|DoCoMo|Obigo|Galaxy Nexus|GT-I9300|GT-N7100|HTC One|Nexus [4|7|S]|Xoom|XT907″) {
set req.http.PS-CapabilityList = req.http.default_ps_capability_list_for_small_screens;
}
# Remove placeholder header values.
remove req.http.default_ps_capability_list_for_large_screens;
remove req.http.default_ps_capability_list_for_large_screens;
}

sub vcl_hash {
# Block 3: Use the PS-CapabilityList value for computing the hash.
hash_data(req.http.PS-CapabilityList);
}
# Block 3a: Define ACL for purge requests
acl purge {
# Purge requests are only allowed from localhost.
“localhost”;
“127.0.0.1″;
#Add your server IP to this list
}
# Block 3b: Issue purge when there is a cache hit for the purge request.
sub vcl_hit {
if (req.request == “PURGE”) {
purge;
error 200 “Purged.”;
}
}

# Block 3c: Issue a no-op purge when there is a cache miss for the purge
# request.
sub vcl_miss {
if (req.request == “PURGE”) {
purge;
error 200 “Purged.”;
}
}

sub vcl_recv {
call generate_user_agent_based_key;

set req.http.X-Forwarded-For = client.ip;
set req.http.Host = regsub(req.http.Host, “:[0-9]+”, “”);

# Block 3d: Verify the ACL for an incoming purge request and handle it.
if (req.request == “PURGE”) {
if (!client.ip ~ purge) {
error 405 “Not allowed.”;
}
return (lookup);
}
# Blocks which decide whether cache should be bypassed or not go here.

# Did not cache the admin and login pages
if (req.url ~ “/wp-(login|admin)”) {
return (pass);
}
// server1 must handle file uploads
if (req.url ~ “media-upload.php” || req.url ~ “file.php” || req.url ~ “async-upload.php”) {
return(pass);
}

// do not cache xmlrpc.php
if (req.url ~ “xmlrpc.php”) {
return(pass);
}

// strip cookies from xmlrpc
if (req.request == “GET” && req.url ~ “xmlrpc.php”){
remove req.http.cookie;return(pass);
}

# Remove the “has_js” cookie
set req.http.Cookie = regsuball(req.http.Cookie, “has_js=[^;]+(; )?”, “”);

# Remove any Google Analytics based cookies
set req.http.Cookie = regsuball(req.http.Cookie, “__utm.=[^;]+(; )?”, “”);

# Remove the Quant Capital cookies (added by some plugin, all __qca)
set req.http.Cookie = regsuball(req.http.Cookie, “__qc.=[^;]+(; )?”, “”);

# Remove the wp-settings-1 cookie
set req.http.Cookie = regsuball(req.http.Cookie, “wp-settings-1=[^;]+(; )?”, “”);

# Remove the wp-settings-time-1 cookie
set req.http.Cookie = regsuball(req.http.Cookie, “wp-settings-time-1=[^;]+(; )?”, “”);

# Remove the wp test cookie
set req.http.Cookie = regsuball(req.http.Cookie, “wordpress_test_cookie=[^;]+(; )?”, “”);

# Are there cookies left with only spaces or that are empty?
if (req.http.cookie ~ “^ *$”) {
unset req.http.cookie;
}

if (req.http.Accept-Encoding) {
# Do no compress compressed files…
if (req.url ~ “\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$”) {
remove req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ “gzip”) {
set req.http.Accept-Encoding = “gzip”;
} elsif (req.http.Accept-Encoding ~ “deflate”) {
set req.http.Accept-Encoding = “deflate”;
} else {
remove req.http.Accept-Encoding;
}
}

# Cache the following files extensions
if (req.url ~ “\.(css|js|png|gif|jp(e)?g)”) {
unset req.http.cookie;
}

# Check the cookies for wordpress-specific items
if (req.http.Cookie ~ “wordpress_” || req.http.Cookie ~ “comment_”) {
return (pass);
}
if (!req.http.cookie) {
unset req.http.cookie;
}

# — End of WordPress specific configuration

# Did not cache HTTP authentication and HTTP Cookie
if (req.http.Authorization || req.http.Cookie) {
# Not cacheable by default
return (pass);
}

# Cache all others requests
return (lookup);

}

# Block 5b: Only cache responses to clients that support gzip. Most clients
# do, and the cache holds much more if it stores gzipped responses.
if (req.http.Accept-Encoding !~ “gzip”) {
return (pass);
}

# Block 6: Mark HTML uncacheable by caches beyond our control.
sub vcl_fetch {
# For static content related to the theme, strip all backend cookies
if (req.url ~ “\.(css|js|png|gif|jp(e?)g)”) {
unset beresp.http.cookie;
}

# A TTL of 30 minutes
set beresp.ttl = 1800s;

return (deliver);
}
# Block 7: Add a header for identifying cache hits/misses.
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = “HIT”;
} else {
set resp.http.X-Cache = “MISS”;
}
}

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current day month ye@r *