Varnish (3) Cache in general and simple static files configuration


Introduction

Varnish is an amazing reverse proxy to accelerate your website, and to reduce the pressure on your server.

Take a look at Varnish official website for more information:
https://www.varnish-cache.org/

This article will show you how to setup a really simple configuration, which will cache all your static content, with Varnish 3. Varnish 4 came out some time ago, so definitely worth to take a look at it. I just had this configuration at my private server, which i have not updated yet.

Installation

The repository should be available allready, so just run apt-get install:

$ sudo apt-get install varnish

How Varnish works

I have made a small diagram, in the simplest possible way i could think of visualizing Varnish object behavior. Bit of explanation under the picture.

Diagram

Explanation

HIT:

  • 1) Client makes a request to Varnish, and lookup the cached object in it's cache. Varnish found the object with success (HIT).
  • 2) Varnish fetches the data to the client, before it gets to the webserver.

MISS:

  • 1) Client makes a request to Varnish, and lookup the cached object in it's cache. Varnish did not find the object with success (MISS).
  • 2) Varnish sends the request further to the webserver.
  • 3) If the object is defined in the Varnish configuration, it will cache the object for 1 hour for the next client to request the Varnish server. The next client will then receive a HIT if the object has been accessed within 1 hour (depends on ttl).
  • 4) The client will get a respond from the webserver.

Configuration

Now we want to setup some cache in front of our webserver. Varnish will be shipped with a default configuration file, called default.vcl (varnish configuration language), located in /etc/varnish/. Open that file, and use the following configuration (which i have commented):

# This is a basic VCL configuration file for varnish.  See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition.  Set this to point to your content
# server.
#

# define backend
backend default {
    # host - just 127.0.0.1 usually for one machine setup
    .host = "127.0.0.1";
    # port - point varnish to what port your backend (webserver) is listening on
    .port = "8080";
}

# beggining of varnish request
sub vcl_recv {
      unset req.http.Accept-Encoding;

  # what files to cache (lookup) - just add if needed
  if (req.url ~ "(?i)\.(jpeg|jpg|png|gif|ico|webp|js|css|txt|pdf|gz|zip|lzma|bz2|tgz|tbz|html|htm)$") {
      return(lookup);
  }
}

# after retrieval from webserver
sub vcl_fetch {
    # what files to handle (the cached ones)  - just add if needed
      if (req.url ~ "(?i)\.(jpeg|jpg|png|gif|ico|webp|js|css|txt|pdf|gz|zip|lzma|bz2|tgz|tbz|html|htm)$") {
        # unset cookies in fetch
        unset beresp.http.Set-Cookie;
        # save cache for 1 hour
        set beresp.ttl = 1h;
  }
}

# how to deliver the output (manipulate output)
sub vcl_deliver {
    # if a varnish object hits, send X-cache header with HIT
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
    # otherwise, send X-cache header with MISS
    } else {
        set resp.http.X-Cache = "MISS";
    }
}

sub vcl_error {
   # handle errors - could eg. be redirect on a specific status code
}

sub vcl_hash {
   #
}

This will cache all filetypes we included, for 1 hour:
jpeg|jpg|png|gif|ico|webp|js|css|txt|pdf|gz|zip|lzma|bz2|tgz|tbz|html|htm

You can always add and remove.

We have pointed our Varnish proxy to listen on backend webserver port 8080. So make sure your webserver is listening on 8080. With Apache, make sure you have changed the following parameters (usually located in /etc/apache/ or /etc/httpd/ somewhere), from 80 to 8080:

# in httpd.conf:
NameVirtualHost *:8080
Listen 8080

# in httpd.conf or a separate site configuration
<VirtualHost *:8080>

Now before we can serve Varnish content at port 80, we need to make sure Varnish itself is pointing at port 80. We need to change this. You can find this under /etc/sysconfig/ in a file simply called varnish. So open the file with your prefered text editor ($ vi /etc/sysconfig/varnish), and change the listening port to port 80. Can be something like this:

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

Now, when everything looks fine, start Varnish:

$ /etc/init.d/varnish start
Validate if Varnish works

To see if Varnish is working, use the histogram program from Varnish, which is really great visualizing the data ("|" is for HIT and "#" is for MISS):

$ varnishhist

Screenshot:

Also, if you do a $ curl -I domain.tld, then you should also be able to see the HIT or MISS X-cache header we added, and some other Varnish headers, like the following:

Via: 1.1 varnish
X-Cache: MISS

More Varnish 3 docs:
https://www.varnish-cache.org/docs/3.0/