Varnish Cache

What Is Varnish?

Varnish is an HTTP accelerator designed for content-heavy dynamic web sites.
Varnish was designed from the ground up as a reverse web accelerator for inbound traffic.

Varnish Installation

Installation was tested on Ubuntu 9.04, 2.6.28-17-generic with Vanish 2.0.6

Download the latest Varnish version.
Extract the archive. Then

sudo ./configure
sudo make
sudo make install

You can find VCL flow here.

For proper installation you need 3 files:
1. sudo vim /etc/varnish.vcl. Default configuration from the official site:

sub vcl_recv {
  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);
  }

  if (req.http.Authorization || req.http.Cookie) {
    /* Not cacheable by default */
    return (pass);
  }
  return (lookup);
}

sub vcl_pipe {
  # Note that only the first request to the backend will have
  # X-Forwarded-For set.  If you use X-Forwarded-For and want to
  # have it set for all requests, make sure to have:
  # set req.http.connection = "close";
  # here.  It is not set by default as it might break some broken web
  # applications, like IIS with NTLM authentication.
  return (pipe);
}

sub vcl_pass {
  return (pass);
}

sub vcl_hash {
  set req.hash += req.url;
  if (req.http.host) {
    set req.hash += req.http.host;
  } else {
    set req.hash += server.ip;
  }
  return (hash);
}

sub vcl_hit {
  if (!obj.cacheable) {
    return (pass);
  }
  return (deliver);
}

sub vcl_miss {
  return (fetch);
}

sub vcl_fetch {
  if (!obj.cacheable) {
    return (pass);
  }
  if (obj.http.Set-Cookie) {
    return (pass);
  }
  set obj.prefetch =  -30s;
  return (deliver);
}

sub vcl_deliver {
  return (deliver);
}

sub vcl_discard {
  /* XXX: Do not redefine vcl_discard{}, it is not yet supported */
  return (discard);
}

sub vcl_prefetch {
  /* XXX: Do not redefine vcl_prefetch{}, it is not yet supported */
  return (fetch);
}

sub vcl_timeout {
  /* XXX: Do not redefine vcl_timeout{}, it is not yet supported */
  return (discard);
}

sub vcl_error {
  set obj.http.Content-Type = "text/html; charset=utf-8";
  synthetic {"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>"} obj.status " " obj.response {"</title>
</head>
<body>
<h1>Error "} obj.status " " obj.response {"</h1>
<p>"} obj.response {"</p>
<h3>Guru Meditation:</h3>
<p>XID: "} req.xid {"</p>
<hr>
<address>
<a href="http://www.varnish-cache.org/">Varnish cache server</a>
</address>
</body>
</html>
"};
  return (deliver);
}

2.  sudo vim /etc/init.d/varnish:

#! /bin/sh
#
# varnish Control the varnish HTTP accelerator
#
# chkconfig: - 90 10
# description: Varnish is a high-perfomance HTTP accelerator
# processname: varnishd
# config: /etc/sysconfig/varnish
# pidfile: /var/run/varnish/varnishd.pid

### BEGIN INIT INFO
# Provides: varnish
# Required-Start: $network $local_fs $remote_fs
# Required-Stop: $network $local_fs $remote_fs
# Should-Start: $syslog
# Short-Description: start and stop varnishd
# Description: Varnish is a high-perfomance HTTP accelerator
### END INIT INFO

# Source function library.
. /lib/lsb/init-functions
retval=0
pidfile=/var/run/varnish.pid
exec="/usr/local/sbin/varnishd"
prog="varnishd"
config="/etc/varnish.vcl"
lockfile="/var/lock/varnish"

# Include varnish defaults

[ -e /etc/default/varnish ] && . /etc/default/varnish
start() {
  if [ ! -x $exec ]
  then
    echo $exec not found
    exit 5
  fi
  if [ ! -f $config ]
    then
    echo $config not found
    exit 6
  fi
  log_daemon_msg "Starting varnish HTTP accelerator"
  log_progress_msg $prog

  # Open files (usually 1024, which is way too small for varnish)
  ulimit -n ${NFILES:-131072}

  # Varnish wants to lock shared memory log in memory.
  ulimit -l ${MEMLOCK:-82000}

  # $DAEMON_OPTS is set in /etc/sysconfig/varnish. At least, one

  # has to set up a backend, or /tmp will be used, which is a bad idea.

  if [ "$DAEMON_OPTS" = "" ]; then
    echo "\$DAEMON_OPTS empty."
    echo -n "Please put configuration options in $config"
    return 6
  else
    echo $DAEMON_OPTS
    # Varnish always gives output on STDOUT
    start-stop-daemon --start --pidfile $pidfile \
    --exec $exec -- -P $pidfile $DAEMON_OPTS > /dev/null 2>&1
    retval=$?
    if [ $retval -eq 0 ]
      then
        log_end_msg 0
      else
        log_end_msg 1
    fi
    return $retval
  fi
}

stop() {
  log_daemon_msg "Stopping varnish HTTP accelerator"
  log_progress_msg $prog
  start-stop-daemon --stop --pidfile $pidfile --retry 10 \
  --exec $exec
  retval=$?
  if [ $retval -eq 0 ] && rm -f $lockfile
  then
    log_end_msg 0
  else
    log_end_msg 1
  fi
  return $retval
}

restart() {
  stop
  start
}

reload() {
  restart
}

force_reload() {
  restart
}

rh_status() {
  status -p $pidfile $prog
}

rh_status_q() {
  rh_status >/dev/null 2>&1
}

# See how we were called.
case "$1" in
  start)
    #rh_status_q && exit 0
    $1
    ;;
  stop)
    #rh_status || exit 0
    $1
    ;;
  restart)
    $1
    ;;
  reload)
    #rh_status_q || exit 7
    $1
    ;;
  force-reload)
    force_reload
    ;;
  status)
    rh_status
    ;;
  condrestart|try-restart)
    #rh_status_q || exit 0
    restart
    ;;
  *)
    echo "Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
    exit 2
esac
exit $?

3. sudo vim /etc/default/varnish

#!/bin/sh
DAEMON_OPTS="-p default_ttl=3600 -f /etc/varnish.vcl -s file,/var/cache/varnish.cache,512M"

4. How to configure Apache read here.


So, what do you think ?