Monday , 24 July 2017
Home > Tech & Web > My Varnish Configuration (default.vcl)
My Varnish Configuration (default.vcl)

My Varnish Configuration (default.vcl)

I thought I’d post my Varnish default.vcl file online for others to see and maybe learn from. I’m very new to Varnish and it took me quite a while to find a few good examples online which I could work from.

I must admit that once set up it’s a very good piece of software which drastically improves the load time of your website.

The configuration options are for this site which is running NGINX, PHP-FPM, APC, Memcache and Varnish.

I’m currently running on a Linode 1GB VPS Server with WordPress as my backend (for those looking to cut a bit of code out of my config).

If you have any experience with Varnish and can offer any improvements for myself and the community please leave them in the comments section below. Thanks.

# We only have one backend to define: NGINX
backend default {
    .host = "127.0.0.1";
    .port = "8080";
}
# Only allow purging from specific IPs
acl purge {
    "localhost";
    "127.0.0.1";
}
sub vcl_recv {
    /* Before anything else we need to fix gzip compression */
    if (req.http.Accept-Encoding) {
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
            # No point in compressing these
            remove req.http.Accept-Encoding;
        } else if (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } else if (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
        } else {
            # unknown algorithm
            unset req.http.Accept-Encoding;
        }
    }
    # Set client IP
    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;
    }
    # Check if we may purge (only localhost)
    if (req.request == "PURGE") {
        if (!client.ip ~ purge) {
            error 405 "Not allowed.";
        }
        return(lookup);
    }
    if (req.request != "GET" &&
        req.request != "HEAD" &&
        req.request != "PUT" &&
        req.request != "POST" &&
        req.request != "TRACE" &&
        req.request != "OPTIONS" &&
        req.request != "DELETE") {
            # /* Non-RFC2616 or CONNECT which is weird. */
            return (pipe);
    }
    if (req.request != "GET" && req.request != "HEAD") {
        # /* We only deal with GET and HEAD by default */
        return (pass);
    }
    # admin users, facebook logged in users, XenForo users and comment authors always miss the cache
    if( req.http.Cookie ~ "xf_session_admin" || req.http.Cookie ~ "xf_session" || req.http.Cookie ~ "wordpress_logged_in_" || req.http.Cookie ~ "fbsr_537171586310880" || req.http.Cookie ~ "wp-postpass" || req.http.Cookie ~ "comment_author_"
	 ){
            return (pass);
    }
    # Remove cookies set by Google Analytics (pattern: '__utmABC')
    if (req.http.Cookie) {
        set req.http.Cookie = regsuball(req.http.Cookie,
            "(^|; ) *__utm.=[^;]+;? *", "\1");
        if (req.http.Cookie == "") {
            remove req.http.Cookie;
        }
    }
    # Remove empty cookies.
    if (req.http.Cookie ~ "^\s*$") {
        unset req.http.Cookie;
    }
    # always pass through POST requests and those with basic auth
    if (req.http.Authorization && req.request == "POST") {
        return (pass);
    }
    # don't cache ajax requests and admin.php from XenForo
    if(req.http.X-Requested-With == "XMLHttpRequest" || req.url ~ "nocache" || req.url ~
"(control.php|wp-comments-post.php|wp-login.php|register.php|admin.php)") {
        return (pass);
    }
    # Do not cache these paths
    if (req.url ~ "^/wp-cron\.php$" ||
        req.url ~ "^/xmlrpc\.php$" ||
        req.url ~ "^/apcstats\.php$" ||
        req.url ~ "^/wp-admin/.*$" ||
        req.url ~ "^/wp-includes/.*$" ||
        req.url ~ "\?s=" ||
        req.url ~ ".*fbconnect.*" ||
        req.url ~ ".*facebook.*" ||
        req.url ~ ".*fblink.*"  ||
        req.url ~ "/community/.*$" ||
        req.url ~ "^/admin\.php$" ) {
            return (pass);
    }
    # Define the default grace period to serve cached content
      if (req.backend.healthy) 	{
    		set req.grace = 60s;
  					}
	else 	{
    		set req.grace = 1h;
  		}
    # remove ?ver=xxxxx strings from urls so css and js files are cached.
    # Watch out when upgrading WordPress, need to restart Varnish or flush cache.
    set req.url = regsub(req.url, "\?ver=.*$", "");
    # By ignoring any other cookies, it is now ok to get a page
    unset req.http.Cookie;
    return (lookup);
}
sub vcl_fetch {
    # remove some headers we never want to see
    unset beresp.http.Server;
    unset beresp.http.X-Powered-By;
    # don't cache admin or forums
    if (req.url ~ "wp-(login|admin)|community") {
    return (hit_for_pass);
    }
    # If WordPress or Facebook OAuth cookies found then page is not cacheable
    if (req.http.Cookie ~"(wp-postpass|wordpress_logged_in|xf_session_admin|xf_session|comment_author_|fbsr_537171586310880)") {
	#beresp.ttl>0 is cacheable so 0 will not be cached
	set beresp.ttl = 0s;
    } else {
       # set beresp.cacheable = true;
	set beresp.ttl=24h;#cache for 24hrs
    }
    # don't cache response to posted requests or those with basic auth
    if ( req.request == "POST" && req.http.Authorization ) {
        return (hit_for_pass);
    }
    # don't cache search results or XML RPC
    if (req.url ~ "\?s=" ||
        req.url ~ "\?P3_NOCACHE" ||
        req.url ~ "xmlrpc.php" ||
        req.url ~ "admin-ajax.php" ) {
            return (hit_for_pass);
    }
    # Handle ESI enabled AdRotate widget
    if (req.url ~ "esihandler.php") {
    set beresp.ttl = 30s;
     }
    else {
    set beresp.do_esi = true;
    set beresp.ttl = 24h;
    }
    # only cache status ok
    if ( beresp.status != 200 ) {
        return (hit_for_pass);
    }
    # If our backend returns 5xx status this will reset the grace time
    # set in vcl_recv so that cached content will be served and
    # the unhealthy backend will not be hammered by requests
    if (beresp.status == 500) {
        set beresp.grace = 1h;
        return (restart);
    }
    # GZip the cached content if possible
    if (beresp.http.content-type ~ "text") {
        set beresp.do_gzip = true;
    }
    # if nothing above matched it is now ok to cache the response
    set beresp.ttl = 24h;
    return (deliver);
}
sub vcl_deliver {
    # remove some headers added by varnish
    unset resp.http.Via;
    unset resp.http.X-Varnish;
}
sub vcl_hit {
    # Set up invalidation of the cache so purging gets done properly
    if (req.request == "PURGE") {
        purge;
        error 200 "Purged.";
    }
    return (deliver);
}
sub vcl_miss {
    # Set up invalidation of the cache so purging gets done properly
    if (req.request == "PURGE") {
        purge;
        error 200 "Purged.";
    }
    return (fetch);
}
sub vcl_error {
    if (obj.status == 503) {
                # set obj.http.location = req.http.Location;
                set obj.status = 404;
        set obj.response = "Not Found";
                return (deliver);
    }
}

Any questions or feedback can be directed to the comments section below and I'll get back to you as soon as I can.  :-D

Get New Posts via Email

Weekly updates sent to your inbox

Become an Author

Travel, write and earn money
Like this page? Show some love and share with friends...

About Paul

Becoming financially independent and travelling the world has been a dream of mine since I was young. In 2012 I decided to dedicate my life to travel. I will document my journey through this site.... View My Full Profile

One comment

  1. FYI–your current Varnish config won’t work for Xenforo. the xf_session cookie is now set for all visitors, including guests. You can use the ‘xf_user’ cookie instead, but ONLY if you force ‘Stay logged in’ to be checked (There’s some addons that do this). Otherwise logged-in users will only have ‘xf_session’ set, and you’ll be caching/displaying logged-in user content to guests.

Scroll To Top