Using Varnish as frontend for Zotonic

Using the Varnish HTTP frontend, you can speed up your Zotonic even more as this web server caches static files intelligently.

Your Varnish config.vcl needs to define a backend for Zotonic:

backend zotonic {
  .host = "127.0.0.1";
  .port = "8000";
  .first_byte_timeout = 300s;
  .connect_timeout = 300s;
  .between_bytes_timeout = 300s;
}

Then, in vcl_recv, specify the Zotonic backend as the default backend:

sub vcl_recv {
  set req.http.X-Forwarded-Host = req.http.host;
  set req.backend   = zotonic;

  ...

Full varnish example configuration file

Please see the Varnish documentation for more information.

#
# Varnish configuration for a Zotonic site
#

backend zotonic_com {
  .host = "127.0.0.1";
  .port = "8000";
  .first_byte_timeout = 300s;
  .connect_timeout = 300s;
  .between_bytes_timeout = 300s;
}

backend nginx {
  .host = "127.0.0.1";
  .port = "8080";
  .first_byte_timeout = 300s;
  .connect_timeout = 300s;
  .between_bytes_timeout = 300s;
}


sub vcl_recv {
  set req.http.X-Forwarded-Host = req.http.host;

  ######################################################################
  ########################### VIRTUAL HOSTS ############################

  if (req.http.host ~ "^(www.|)(zotonic|example).(com|net)$") {
    set req.backend   = zotonic_com;
  }
  # Nginx hosted sites
  #
  else {
    set req.backend   = nginx;
  }

  ######################################################################

  # Add a unique header containing the client address
  unset req.http.X-Forwarded-For;
  set   req.http.X-Forwarded-For = client.ip;

  # We only deal with GET and HEAD by default
  if (req.request != "GET" && req.request != "HEAD") {
    return (pass);
  }

  # Cache the home page for a short period (ttl = 1 second, see vcl_fetch)
  if (req.url ~ "^/$") {
    unset req.http.Cookie;
    unset req.http.Authenticate;
    set req.grace = 10s;
    return (lookup);
  }

  # Cache served css and media files
  if (req.url ~ "^/(lib|image|media|favicon.ico)/") {
    unset req.http.Cookie;
    unset req.http.Authenticate;
    set req.grace = 30m;
    return (lookup);
  }

  return (pass);
}


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";
    return (pipe);
}


sub vcl_pass {
  if (req.url ~ "^/comet") {
    #bereq.connect_timeout = 70;
    #bereq.first_byte_timeout = 70;
  }
  return (pass);
}


sub vcl_fetch {
  if (req.url ~ "^/(lib|image|media|favicon.ico)/") {
    unset beresp.http.Set-Cookie;
    set beresp.grace = 30m;
    set beresp.ttl = 10m;
    return (deliver);
  }
  return (pass);
}

sub vcl_error {
  if (obj.status == 503 && req.restarts < 4) {
    restart;
  }
}


Auto-starting Varnish on Mac OSX

To automatically start Varnish on Max OSX, add the following plist file to launchd.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Disabled</key>
    <false/>
    <key>KeepAlive</key>
    <false/>
    <key>Debug</key>
    <false/>
    <key>Label</key>
    <string>varnishd</string>
    <key>OnDemand</key>
    <false/>
    <key>GroupName</key>
    <string>wheel</string>
    <key>UserName</key>
    <string>root</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/sbin/varnishd</string>
        <string>-F</string>
        <string>-a</string>
        <string>:80</string>
        <string>-T</string>
        <string>localhost:6082</string>
        <string>-f</string>
        <string>/usr/local/etc/varnish/varnish.zotonic.vcl</string>
        <string>-s</string>
        <string>malloc</string>
        <string>-u</string>
        <string>nobody</string>
    </array>
    <key>RunAtLoad</key>
    <false/>
</dict>
</plist>

HTTPS support Deployment Proxying Zotonic with nginx

Referred by

Running on Port 80 and Port 443

Using standard ports helps visitors discover your page and removes the awkward port number from URLs.