Back to post index

Using the varnish cache
Tags: [varnish]
Published: 12 Nov 2013 20:33

Building Varnish from source

Installation follows the standard installation procedure of ./configure && make && make install:

# wget 'http://repo.varnish-cache.org/source/varnish-3.0.4.tar.gz'
# tar xzof varnish-3.0.4.tar.gz
# cd varnish-3.0.4
# ./configure
# make -j8

Here I experienced errors:

varnishadm.c:48:33: error: editline/readline.h: No such file or directory

To fix this, simply install the readline and editline development headers:

# apt-get install libreadline6-dev libeditline0 libeditline-dev

I had to start again from scratch:

# make clean
# ./configure
# make -j8

This time it was successful.

The next step is to install:

# make install

Configuring Varnish

Varnish uses the VCL language to describe how it handles requests and caches results.

To default to caching for a standard HTTP server, create the following file:

/etc/varnish/default.vcl:

backend default {
        .host = "127.0.0.1";
        .port = "29001";
}

In my case, my web server listened for connections on port 29001.

Prepare the following directory:

# mkdir /var/log/varnish

To run the varnish daemon:

# varnishd -a :80 -f /etc/varnish/default.vcl -u varnish -g varnish -s malloc,100M

The following varnishd man page options are relevant:

   -a address[:port][,address[:port][...]
          Listen  for  client  requests on the specified address and port.

   -f config
          Use  the specified VCL configuration file instead of the builtin
          default.

   -u user
          Specifies  the  name  of an unprivileged user to which the child
          process should switch before it  starts  accepting  connections.

   -g group
          Specifies  the  name of an unprivileged group to which the child
          process should switch before it  starts  accepting  connections.

   -s [name=]type[,options]
          Use the specified storage backend.

To log to a file, use varnishncsa:

# varnishncsa -a -w /var/log/varnish/access.log -P /var/run/varnishncsa.pid -D

The following varnishncsa man page options are relevant:

   -a     When writing to a file, append to it rather than overwrite it.

   -D     Daemonize.

   -P file
          Write the process's PID to the specified file.

   -w file
          Write  log entries to file instead of displaying them.  The file
          will be overwritten unless the -a option was specified.

Make sure to test your connection after starting the varnishd daemon.

varnishstat shows hit rate of 0

When I ran varnishstat to make sure everything was ok, I saw that the hit rate was 0. This meant that there were a constant stream of cache misses.

I had to add the following lines to /etc/varnish/default.vcl based on https://www.varnish-cache.org/trac/wiki/VarnishAndWordpress:

# Drop any cookies sent to Wordpress.
sub vcl_recv {
    unset req.http.cookie;
}

# Drop any cookies Wordpress tries to send back to the client.
sub vcl_fetch {
    unset beresp.http.set-cookie;
}

After this, I saw a much better hit rate:

Hitrate ratio:        1        1        1
Hitrate avg:     0.8636   0.8636   0.8636

Manually purging entries when you update

Unfortunately, after that add, varnish would not update when I made changes to this blog.

Refering to https://www.varnish-cache.org/docs/trunk/users-guide/purging.html, I modified my default.vcl:

backend default {
        .host = "127.0.0.1";
        .port = "29001";
}

# Invalidate cache entries
# Drop any cookies sent to us.
# Drop any cookies we try to send back to the client.

acl purge {
        "localhost";
}

sub vcl_recv {
        unset req.http.cookie;

        if (req.request == "PURGE") {
                if (!client.ip ~ purge) {
                        error 405 "Not allowed.";
                }
                return (lookup);
        }
}

sub vcl_fetch {
        unset beresp.http.set-cookie;
}

sub vcl_hit {
        if (req.request == "PURGE") {
                purge;
                error 200 "Purged.";
        }
}

sub vcl_miss {
        if (req.request == "PURGE") {
                purge;
                error 200 "Purged.";
        }
}

Note: I had to combine the sub vcl_recv entries.

After this, a call to curl would allow me to selectively purge cache entries:

# curl -H "Host: operand.ca" -X PURGE 127.0.0.1/2013/11/12/using-the-varnish-cache.html