Skip to content

Instantly share code, notes, and snippets.

@sameg14
Created February 13, 2014 04:05
Show Gist options
  • Save sameg14/8969563 to your computer and use it in GitHub Desktop.
Save sameg14/8969563 to your computer and use it in GitHub Desktop.
perfect varnish caching for joomla
# 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.
#
backend default {
.host = "127.0.0.1";
.port = "8000";
}
# Place the following 2 configuration blocks right after your "backend default {…}" block
# inside your /etc/varnish/default.vcl file (the main Varnish configuration file)
# This Varnish configuration makes use of a custom HTTP header to determin whether
# some user is logged in or not inside Joomla! To allow this, simply append this code
# // Set user state in headers
# if (!$user->guest) {
# JResponse::setHeader('X-Logged-In', 'True', true);
# } else {
# JResponse::setHeader('X-Logged-In', 'False', true);
# }
# on the "function onAfterInitialise(){ ... } function, right after "$user= JFactory::getUser();"
# in the Joomla! cache plugin php file located at /plugins/system/cache/cache.php
# Finally, enable this plugin via the Joomla! backend.
# If you don't want to use the cache plugin, add this code in your template's index.php file.
# Don't forget to prepend it with "$user = JFactory::getUser();"
# The following setup assumes a 5 min cache time - you can safely drop this to 1 min for popular/busy sites
sub vcl_recv {
# Forward client's IP to backend
remove req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
# Proxy (pass) any request that goes to the backend admin,
# the banner component links or any post requests
# You can add more pages or entire URL structure in the end of the "if"
if(req.http.cookie ~ "userID" || req.url ~ "^/administrator" || req.url ~ "^/component/banners" || req.request == "POST") {
return (pass);
}
# Check for the custom "x-logged-in" header to identify if the visitor is a guest,
# then unset any cookie (including session cookies) provided it's not a POST request
if(req.http.x-logged-in == "False" && req.request != "POST"){
unset req.http.cookie;
}
# Properly handle different encoding types
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)$") {
# No point in compressing these
remove req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
# unknown algorithm (aka crappy browser)
remove req.http.Accept-Encoding;
}
}
# Cache files with these extensions
if (req.url ~ "\.(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)$") {
return (lookup);
}
# Set how long Varnish will cache content depending on whether your backend is healthy or not
if (req.backend.healthy) {
set req.grace = 5m;
} else {
set req.grace = 1h;
}
return (lookup);
}
sub vcl_fetch {
# Check for the custom "x-logged-in" header to identify if the visitor is a guest,
# then unset any cookie (including session cookies) provided it's not a POST request
if(req.request != "POST" && beresp.http.x-logged-in == "False") {
unset beresp.http.Set-Cookie;
}
# Allow items to be stale if needed (this value should be the same as with "set req.grace"
# inside the sub vcl_recv {…} block (the 2nd part of the if/else statement)
set beresp.grace = 1h;
# Serve pages from the cache should we get a sudden error and re-check in one minute
if (beresp.status == 503 || beresp.status == 502 || beresp.status == 501 || beresp.status == 500) {
set beresp.grace = 60s;
return (restart);
}
# Unset the "etag" header (suggested)
unset beresp.http.etag;
# This is Joomla! specific: fix stupid "no-cache" header sent by Joomla! even
# when caching is on - make sure to replace 300 with the number of seconds that
# you want the browser to cache content
if(beresp.http.Cache-Control == "no-cache" || beresp.http.Cache-Control == ""){
set beresp.http.Cache-Control = "max-age=300, public, must-revalidate";
}
# This is how long Varnish will cache content
set beresp.ttl = 5m;
return (deliver);
}
#
# Below is a commented-out copy of the default VCL logic. If you
# redefine any of these subroutines, the built-in logic will be
# appended to your code.
# sub vcl_recv {
# if (req.restarts == 0) {
# if (req.http.x-forwarded-for) {
# set req.http.X-Forwarded-For =
# req.http.X-Forwarded-For + ", " + client.ip;
# } else {
# set req.http.X-Forwarded-For = client.ip;
# }
# }
# 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 bereq.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 {
# hash_data(req.url);
# if (req.http.host) {
# hash_data(req.http.host);
# } else {
# hash_data(server.ip);
# }
# return (hash);
# }
#
# sub vcl_hit {
# return (deliver);
# }
#
# sub vcl_miss {
# return (fetch);
# }
#
# sub vcl_fetch {
# if (beresp.ttl <= 0s ||
# beresp.http.Set-Cookie ||
# beresp.http.Vary == "*") {
# /*
# * Mark as "Hit-For-Pass" for the next 2 minutes
# */
# set beresp.ttl = 120 s;
# return (hit_for_pass);
# }
# return (deliver);
# }
#
# sub vcl_deliver {
# return (deliver);
# }
#
# sub vcl_error {
# set obj.http.Content-Type = "text/html; charset=utf-8";
# set obj.http.Retry-After = "5";
# 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>
# <p>Varnish cache server</p>
# </body>
# </html>
# "};
# return (deliver);
# }
#
# sub vcl_init {
# return (ok);
# }
#
# sub vcl_fini {
# return (ok);
# }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment