Optimizing Your Headway Website – Installing Varnish

In our series we have been looking at various places in a web server stack to make adjustments, finely tune, or even install new components to help us get a wicked fast server. Today we are going to look at installing Varnish. This tutorial is going to cover both Apache and Nginx versions to get you up and running with Varnish today.

Varnish is a HTTP accelerator and a great tool to help speed up your server. It works by redirecting users to static pages and only drawing on the server if there is a need for an active process.

Before you start this tutorial, you need to make sure you have a LAMP (Apache) or LEMP (Nginx) install. In our third step we will detour to the Apache and Nginx specifics.

Step 1 – Installing Varnish

The Varnish site recommends that if you are going to install, you install from their repository, so you won’t be able to do a simple apt-get install just yet.

We need to first grab the repository.

sudo curl http://repo.varnish-cache.org/debian/GPG-key.txt | sudo apt-key add -

Next we need to add the repository to the list of apt sources. We we will open up this file.

sudo nano /etc/apt/sources.list

And we’ll add the following line to the bottom of the list.

deb http://repo.varnish-cache.org/ubuntu/ lucid varnish-3.0

Save the file and exit. Finally run the update and install commands.

sudo apt-get update
sudo apt-get install varnish

Step Two – Configure Varnish

With Varnish installed, we are going to configure it a bit.

Varnish is going to serve content on port 80, while fetching it from Apache or Nginx, which we will set them up to run on port 8080 in a little bit.

So let’s go ahead and start getting Varnish setup by opening:

sudo nano /etc/default/varnish

Find the lines under “DAEMON_OPTS” — in the Alternative 2 section and change the port to 80. It should be by “-a.” You configuration should match the following:

DAEMON_OPTS="-a :80 
-T localhost:6082 
-f /etc/varnish/default.vcl 
-S /etc/varnish/secret 
-s malloc,256m"

That’s the only change we need to make in that file. So save it and let’s open the default.vcl file to make changes there.

sudo nano /etc/varnish/default.vcl

So this file tell varnish where to look for the webserver content. It should already be configured to have a backend listening in on port 8080.

Now we also need to use this file for a secondary purpose. WordPress is full of various cookies that will make caching difficult. In order to get varnish to work as efficiently as possible, we need to have it drop all cookies that don’t relate to the admin side of WordPress (think wp-admin).

The beginning of the default.vcl file should look like this:

[…]
backend default {
.host = "127.0.0.1";
.port = "8080";
}
#Drop any cookies from being sent to WordPress
sub vcl_recv {
if (!(req.url ~ "wp-(login|admin)")) {
unset req.http.cookie;
}
}
#Drop any cookies WordPress tries to send back to client.
sub vcl_fetch {
if (!(req.url ~ "wp-(login|admin)")) {
unset beresp.http.set-cookie;
}
}
[...]

Step Three – Configure Nginx / Apache

I’m going to break these into 3a for Nginx and 3b for Apache.

Step 3a – Configure Nginx

So we’ve got Varnish working on port 80, we need to get nginx to run on port 8080. Nginx by default was running port 80.

Open up the virtual host file with the WordPress information. In our previous Nginx tutorial, we simply called it WordPress.

sudo nano /etc/nginx/sites-available/wordpress

Our Virtual Host file should also be set to port 8080 and be only accessbiel from the localhost. So we should update the following line replacing 80 with 8080.

server {
listen 127.0.0.1:8080; # listen for ipv4; this line is default and implied
}

We must do one last thing prior to starting varnish running on our site, and that is to remove the default enabled virtual host.

sudo rm /etc/nginx/sites-enabled/default

The template will remain in the sites-available directory, should you need it again.

Finally you should just need to restart nginx.

sudo service nginx restart
sudo service varnish restart

Step 3a – Configure Apache

For those running Apache, we’re going to edit Apache’s config file and get Apache running to port 8080 instead of port 80.

We will go ahead and open up the apache ports file:

sudo nano /etc/apache2/ports.conf

Now let’s change the port number for both the NameVirtualHost and the Listen line to port 8080, and we need to make sure that it is only accessible from the localhost. So our configuration should look like this:

NameVirtualHost 127.0.0.1:8080
Listen 127.0.0.1:8080

Change these settings in the default virtual host file as well:

sudo nano /etc/apache2/sites-available/default

Our Virtual Host should also be set to port 8080, and that updated line should look like this:

<VirtualHost 127.0.0.1:8080>

Now go ahead and save the changes and proceed to restart Apache and Varnish.

sudo service apache2 restart
sudo service varnish restart

Step 4 – Checking Varnish

So assuming that you didn’t have issues in our prior steps. If you were to access your domain in a browser it should instantly take you to the varnish cached versions.

You can check the details of Varnish with the following command:

varnishstat

And that’s it!

Spread the word!

One Response

  1. Thanks AJ, I have been playing with Varnish for a while and love the additional speed it brings!

    Here is an alternative (and slighly more complex) VCL than the one above.

    I would be interested to know how this looks, and if there is there is anything that can be done to improve it?

    `backend default {
    .host = “192.168.1.120”;
    .port = “82”;
    }

    sub vcl_recv {
    if (req.url ~ “.(png|gif|jpg|swf|css|js)$”) {
    return(lookup);
    }
    }

    # strip the cookie before the image is inserted into cache.

    sub vcl_fetch {
    if (req.url ~ “.(png|gif|jpg|swf|css|js)$”) {
    unset beresp.http.set-cookie;
    }
    }

    import std;

    include “lib/xforward.vcl”;
    # include “lib/cloudflare.vcl”;
    include “lib/purge.vcl”;
    include “lib/bigfiles.vcl”; # Varnish 3.0.3+
    #include “lib/bigfiles_pipe.vcl”; # Varnish 3.0.2
    include “lib/static.vcl”;

    acl purge {
    “localhost”;
    “127.0.0.1”;
    }

    # Pick just one of the following:
    # (or don’t use either of these if your application is “responsive”)
    # include “lib/mobile_cache.vcl”;
    # include “lib/mobile_pass.vcl”;

    ### WordPress-specific config ###
    # This config was initially derived from the work of Donncha Ó Caoimh:
    # http://ocaoimh.ie/2011/08/09/speed-up-wordpress-with-apache-and-varnish/
    sub vcl_recv {
    # pipe on weird http methods
    if (req.request !~ “^GET|HEAD|PUT|POST|TRACE|OPTIONS|DELETE$”) {
    return(pipe);
    }

    ### Check for reasons to bypass the cache!
    # never cache anything except GET/HEAD
    if (req.request != “GET” && req.request != “HEAD”) {
    return(pass);
    }
    # don’t cache logged-in users or authors
    if (req.http.Cookie ~ “wp-postpass_|wordpress_logged_in_|comment_author|PHPSESSID”) {
    return(pass);
    }
    # don’t cache ajax requests
    if (req.http.X-Requested-With == “XMLHttpRequest”) {
    return(pass);
    }
    # don’t cache these special pages
    if (req.url ~ “nocache|wp-admin|wp-(comments-post|login|activate|mail).php|bb-admin|server-status|control.php|bb-login.php|bb-reset-password.php|register.php”) {
    return(pass);
    }

    ### looks like we might actually cache it!
    # fix up the request
    set req.grace = 2m;
    set req.url = regsub(req.url, “?replytocom=.*$”, “”);

    # Remove has_js, Google Analytics __*, and wooTracker cookies.
    set req.http.Cookie = regsuball(req.http.Cookie, “(^|;s*)(__[a-z]+|has_js|wooTracker)=[^;]*”, “”);
    set req.http.Cookie = regsub(req.http.Cookie, “^;s*”, “”);
    if (req.http.Cookie ~ “^s*$”) {
    unset req.http.Cookie;
    }

    return(lookup);
    }

    sub vcl_hash {
    # Add the browser cookie only if a WordPress cookie found.
    if (req.http.Cookie ~ “wp-postpass_|wordpress_logged_in_|comment_author|PHPSESSID”) {
    hash_data(req.http.Cookie);
    }
    }

    sub vcl_fetch {
    # make sure grace is at least 2 minutes
    if (beresp.grace < 2m) {
    set beresp.grace = 2m;
    }

    # catch obvious reasons we can't cache
    if (beresp.http.Set-Cookie) {
    set beresp.ttl = 0s;
    }

    # Varnish determined the object was not cacheable
    if (beresp.ttl <= 0s) {
    set beresp.http.X-Cacheable = "NO:Not Cacheable";
    return(hit_for_pass);

    # You don't wish to cache content for logged in users
    } else if (req.http.Cookie ~ "wp-postpass_|wordpress_logged_in_|comment_author|PHPSESSID") {
    set beresp.http.X-Cacheable = "NO:Got Session";
    return(hit_for_pass);

    # You are respecting the Cache-Control=private header from the backend
    } else if (beresp.http.Cache-Control ~ "private") {
    set beresp.http.X-Cacheable = "NO:Cache-Control=private";
    return(hit_for_pass);

    # You are extending the lifetime of the object artificially
    } else if (beresp.ttl = 500) {
    set beresp.ttl = 0s;
    set beresp.grace = 15s;
    }

    # Deliver the content
    return(deliver);
    }`

Leave a reply

Copyright © 2016 Vesped Inc. All Rights Reserved. Proudly Powered by Headway and WordPress