Varnish Server
Probably the biggest reason Varnish isn't seen more often in Joomla setups is its configuration. Varnish VCL configuration files are complex and large but they're really not that complicated.
I started with a configuration created by fevangelou titled: The perfect Varnish configuration for WordPress, Joomla, Drupal & other (common) CMS based websites. I found that configuration to be less than ideal for Joomla. The limitations are pretty extensive, but I'll sum them up in just a few bullets:
- Config contains Wordpress and Drupal specific configs
- List of pages to NOT cache is static
- Not well documented
- It has comments, but the Wordpress, Drupal, and Joomla configs are all mixed together. I only care about the Joomla configs.
None of that is a criticism for the original author - their config was my starting point.
Using my (free) System - Expires Headers plugin, we can reduce the non-caching page list to just a few entries that are universal to Joomla installations. Using the plugin to control cached pages is discussed below the Varnish config.
/etc/varnish/default.vcl
Um... I'm not putting the whole config file here. Even pared down, it's still over 300 lines long. I'll cover the highlights here, and just let you download the config file. Remember to edit it for your environment!!!
There are some basic configs that I'm just going to breeze over. For the most part, there are 4 sections you'll want to understand. Let's breeze over those bits first.
These are commented, so you can pretty much read what each bit does in the comments above it.
- vcl - defines which version of Varnish your config is intended for.
- import - allows you to bring in additional functionality
- backend - allows you to define the source where Varnish retrieves its content
- director - useful if you have multiple backends and wish to load-balance
Action Sections
These are where the Varnish magic happens. This is also where you'll find the main differences between my configuration and that provided by fevangelou. I chose to focus on Joomla configuration, and to simplify the configuration using a plugin to define non-cached pages. This removed dozens of lines from the config file.
I'm not going into detail, this is a broad overview of what's happening in each section. The sections are heavily commented, and should be relatively self-explanatory.
When you see the following commands, this is what they mean:
- return(pass) - tells Varnish to pass the request to the backend rather than try and serve it from cache.
- return(pipe) - means Varnish stops inspecting each request, and just sends bytes straight to the backend.
- return(hash) - tell Varnish to deliver content from cache even if the request otherwise indicates that the request should be passed.
- return(deliver) - send the page to the browser
sub vcl_recv
This section examines the incoming request and determines what to do with it. We do fun things in this section in preparation for the response. One of the first things is attaching the client IP address to a special header in order to hand it over to Joomla. We also strip out cookies that are unnecessary.
We also inspect several header and cookie values to determine if the request should NOT be served from cache. I opt to ALWAYS serve fresh pages to users who are logged in, so we look for the joomla_user_state cookie and act upon it if it's found
Likewise, there are some URLs that will never get cached - 2, to be precise. /administrator and com_ajax. If the page is requested with XMLHttpRequest, it's also some kind of AJAX call, and those aren't cached.
Basically, you'll want to take a peek at this section and determine if there's something it's doing that you don't want it to do (or something it's NOT doing, perhaps another URL or cookie to pay attention to.)
The good news is, I stripped out all of the WP and Drupal stuff, so if it's in there - it's only stuff that's Varnish and Joomla related.
sub vcl_backend_response
Super similar to the previous section, this section deals with the response from the backend servers. There are various details you'll want to read through, but here are the highlights:
- We don't cache errors (5xx status codes)
- We don't cache if the page has ANY negative caching headers (no-store, no-cache, must-revalidate, Pragma=no-cache).
- The same pages that aren't allowed in the previous section aren't allowed to be cached here.
- POST requests are not cached
- Cookies are unset for guests to prevent them from being stored with cached pages
- We set some cache duration values
Again, I stripped out anything to do with WP or Drupal - the only things left in this section is Varnish and Joomla related.
sub vcl_deliver
Final checks, setting Expires headers if they aren't already set, some cache headers (that the load balancer removes), and finally sending the response to the browser.