Tutorial: Setting up Varnish with Apache.


Posted by Andrew McCombe on Fri Dec 24, 2010


Varnish is an HTTP accelerator designed for content-heavy dynamic web sites. In contrast to other HTTP accelerators, such as Squid, which began life as a client-side cache, or Apache, which is primarily an origin server, Varnish was designed from the ground up as an HTTP accelerator.

Here’s how to set up varnish with Apache.
Tested on Ubuntu 10.04 (Lucid) Server LTS.


1. Install varnish:

sudo apt-get install varnish

2. Configure varnish to serve on 80 and fetch from 8008:

vim /etc/default/varnish

DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G
vim /etc/varnish/default.vcl

backend apache {
        .host = "127.0.0.1";
        .port = "8008";
}
acl purge {
        "localhost";
        "127.0.0.1";
}
sub vcl_recv {
        // Strip cookies for static files:
        if (req.url ~ "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$") {
                unset req.http.Cookie;
                return(lookup);
        }
        // Remove has_js and Google Analytics __* cookies.
        set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", "");
        // Remove a ";" prefix, if present.
        set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
        // Remove empty cookies.
        if (req.http.Cookie ~ "^\s*$") {
                unset req.http.Cookie;
        }
        if (req.request == "PURGE") {
                if (!client.ip ~ purge) {
                        error 405 "Not allowed.";
                }
                purge("req.url ~ " req.url " && req.http.host == " req.http.host);
                error 200 "Purged.";
        }
}
sub vcl_hash {
  if (req.http.Cookie) {
    set req.hash += req.http.Cookie;
  }
}
sub vcl_fetch {
        // Strip cookies for static files:
        if (req.url ~ "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$") {
                unset beresp.http.set-cookie;
        }
        // Varnish determined the object was not cacheable
        if (!beresp.cacheable) {
                set beresp.http.X-Cacheable = "NO:Not Cacheable";
        } elsif(req.http.Cookie ~"(UserID|_session)") {
            // You don't wish to cache content for logged in users
                set beresp.http.X-Cacheable = "NO:Got Session";
                return(pass);
        }  elsif ( beresp.http.Cache-Control ~ "private") {
                 // You are respecting the Cache-Control=private header from the backend
                set beresp.http.X-Cacheable = "NO:Cache-Control=private";
                return(pass);
        } elsif ( beresp.ttl < 1s ) {
                // You are extending the lifetime of the object artificially
                set beresp.ttl   = 300s;
                set beresp.grace = 300s;
                set beresp.http.X-Cacheable = "YES:Forced";
        }  else {
                // Varnish determined the object was cacheable
                set beresp.http.X-Cacheable = "YES";
        }
        return(deliver);
}

4. Set apache to listen on port 8008:

vim /etc/apache2/ports.conf

NameVirtualHost *:8008
Listen 8008


5. Set all vhosts to listen on port 8008:

vim /etc/apache2/sites-enabled/000-default
<Virtualhost *:8008>
 ...
</Virtualhost>

Do the same for all other vhosts.

6. Restart Apache and Varnish:

service apache2 restart
service varnish restart

7. Test varnish:

curl -I http://www.euperia.com/linux/setting-up-varnish-with-apache-tutorial/

HTTP/1.1 200 OK
Server: Apache
X-Pingback: http://www.euperia.com/xmlrpc.php
Link: ; rel=shortlink
Vary: Accept-Encoding,User-Agent
Content-Type: text/html; charset=UTF-8
X-Cacheable: YES
Content-Length: 22992
Date: Wed, 05 Jan 2011 22:01:22 GMT
X-Varnish: 769719461 769719459
Age: 7
Via: 1.1 varnish
Connection: keep-alive

Notice the Varnish headers? There are also a couple of these. Age shows the age of the item in the Varnish cache.

Links

A good set of links can be found here:

Update: 17th Feb 2012

There is also a great set of instructions over at ocaoimh.ie.