Revision of Varnish from Wed, 03/09/2011 - 12:32

Revisions allow you to track differences between multiple versions of your content, and revert back to older versions.

Accelerate your Drupal/Pressflow site using Varnish

The primary reason for switching to Pressflow is to use an HTTP accelerator such as Varnish
Apache Configuration
Adjust your Apache configuration to server the Drupal site on port 8080. Edit your Apache conf file and add:

Listen 8080
NameVirtualHost *:8080

Restart Apache and make sure you can access your site on that port.

Varnish Configuration
Rather than change the default Varnish conf file, we'll create one just for Drupal:/usr/local/etc/varnish/drupal.vcl with the basic configuration from FourKitchens that has a couple adjustments to it:

backend default {
  .host = "127.0.0.1";
  .port = "8080";
  .connect_timeout = 600s;
  .first_byte_timeout = 600s;
  .between_bytes_timeout = 600s;
}

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);
  }

  // Remove has_js and Google Analytics cookies.
  set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|__utma_a2a|has_js)=[^;]*", "");

  // To users: if you have additional cookies being set by your system (e.g.
  // from a javascript analytics file or similar) you will need to add VCL
  // at this point to strip these cookies from the req object, otherwise
  // Varnish will not cache the response. This is safe for cookies that your
  // backed (Drupal) doesn't process.
  //
  // Again, the common example is an analytics or other Javascript add-on.
  // You should do this here, before the other cookie stuff, or by adding
  // to the regular-expression above.

  // 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.http.Authorization || req.http.Cookie) {
    /* Not cacheable by default */
    return (pass);
  }

  // Skip the Varnish cache for install, update, and cron
  if (req.url ~ "install\.php|update\.php|cron\.php") {
    return (pass);
  }

  // Normalize the Accept-Encoding header
  // as per: http://varnish-cache.org/wiki/FAQ/Compression
  if (req.http.Accept-Encoding) {
    if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
      # No point in compressing these
      remove req.http.Accept-Encoding;
    }
    elsif (req.http.Accept-Encoding ~ "gzip") {
      set req.http.Accept-Encoding = "gzip";
    }
    else {
      # Unknown or deflate algorithm
      remove req.http.Accept-Encoding;
    }
  }

  // - everything in most of the standard drupal directories.
  // - txt and ico files (most important: robots.txt and favicon.ico)
  if (req.url ~ "^/(files|misc|sites|themes|modules)/" || req.url ~ "\.(txt|ico)$") {
    unset req.http.Cookie;
  }

  // Drupal js/css doesn't need cookies, cache them
  if (req.url ~ "^/modules/.*\.(js|css)\?") {
    unset req.http.Cookie;
  }

  // Let's have a little grace
  set req.grace = 30s;

  return (lookup);
}

sub vcl_hash {
   if (req.http.Cookie) {
     set req.hash += req.http.Cookie;
   }
}

// Strip any cookies before an image/js/css is inserted into cache.
sub vcl_fetch {
   if (req.url ~ "\.(png|gif|jpg|swf|css|js)$") {
     // This is for Varnish 2.0; replace obj with beresp if you're running
     // Varnish 2.1 or later.
     unset beresp.http.set-cookie;
   }
}

sub vcl_error {
   // Let's deliver a friendlier error page.
   // You can customize this as you wish.
   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>
       <style type="text/css">
       #page {width: 400px; padding: 10px; margin: 20px auto; border: 1px solid black; background-color: #FFF;}
       p {margin-left:20px;}
       body {background-color: #DDD; margin: auto;}
       </style>
     </head>
     <body>
     <div id="page">
     <h1>Page Could Not Be Loaded</h1>
     <p>We're very sorry, but the page could not be loaded properly. This should be fixed very soon, and we apologize for any inconvenience.</p>
     <hr />     <h4>Debug Info:</h4>
     <pre>
Status: "} obj.status {"
Response: "} obj.response {"
XID: "} req.xid {"
</pre>
       <address><a href="http://www.varnish-cache.org/">Varnish</a></address>
       </div>
     </body>
    </html>
    "};
    return (deliver);
}

Drupal configuration
Edit your site's settings.php file and add your proxy to the $conf array, keeping any other settings that are there:

$conf = array(
    'reverse_proxy' => TRUE,
    'reverse_proxy_addresses' => array(
      '127.0.0.1', // Varnish web proxy
    ),
  );

Enable Drupal's page cache in admin/settings/performance and set the Caching Mode to External and Page Cache Maximum Age to an appropriate value (anything over 0).

Extra Header Information
Add some extra HTTP header details to tell whether the page you are getting came from the Varnish cache by adding this snippet to /usr/local/etc/varnish/drupal.vcl:

sub vcl_deliver {
  #add cache hit data
  if (obj.hits > 0) {
    #if hit add hit count
    set resp.http.X-Varnish-Cache = "HIT";
    set resp.http.X-Cache-Hits = obj.hits;
  } else {
    set resp.http.X-Varnish-Cache = "MISS";
  }
}

Grace for Misbehaving Backends
http://varnish-cache.org/trac/wiki/VCLExampleGrace

sub vcl_recv {
  if (req.backend.healthy) {
    set req.grace = 30s;
  } else {
    set req.grace = 1h;
  }
}

sub vcl_fetch {
   set beresp.grace = 1h;
}

Testing Varnish
You can test that Varnish is serving a cached page or not with:

curl -I http://yoururl.com

Resources
Pressflow, Varnish and Caching … oh my! - their Google Analytics cookie code works. Also a sample VCL file
https://wiki.fourkitchens.com/display/PF/Configure+Varnish+for+Pressflow
http://janaksingh.com/blog/install-pressflow-drupal-varnish-apc-and-apache-centos-55-130
Using Pressflow behind a reverse proxy cache
Drupal, Varnish and Pressflow, Fast delivery to the customer with some speed for users too
Example Varnish VCL for Drupal/Pressflow Sites

Recent Updates

  • 3 months 3 weeks ago
  • 3 months 3 weeks ago
  • 3 months 3 weeks ago
    php 8.x
  • 3 months 3 weeks ago
    10.6.7
  • 3 months 4 weeks ago
    Drop Centos 5/6 stuff