Varnish

Turpentine Module

Before we can utilise Varnish we need to install the Turpentine module provided by Nexcess https://github.com/nexcess/magento-turpentine/

Once installed, it is important the care is taken to configure the settings in System/Configuration to work with your Varnish instance. This page is about Magento 1 with Varnish, not Varnish explicitly and so we won't cover how to install and configure Varnish itself.

Version, Secret and Server Address

Turpentine will need to know the IP that is hosting Varnish, this can be a local server or a remote server on a separate server. E.g: 127.0.0.1:6082

Be sure to check what version of Varnish you are using, this can be found by running varnishd -V Turpentine supports Varnish versions 2.x, 3.x, 4.0.x and 4.1.x. You can leave this set to auto or set an explicit version.

Varnish works with a secret string for security reasons, Turpentine requires this to work. The secret can be found at /etc/varnish/secret it will need to be pasted in to the relative input and a line break escape sequence appending to it like:

mysupersecretvarnishkey\n

VCL file

For Varnish to work correctly, we need to use the VCL file that is generated by Turpentine, it is by default generated to ./var/default.vcl You can either symlink /etc/varnish/default.vcl to the dumped file or overwrite your standard Varnish VCL file.

It is easier to maintain if a symlink is used as opposed to a direct copy, or Varnish configuration can be edited to point to your Magento VCL. This is important because Turpentine will update the VCL depending on it's configuration in Magento.

Troubleshooting

Turpentine by default is configured to handle the standard out of the box Magento themes although it is not always perfect. There are a number of issues that may be encountered that are affected by different environments. See the Wiki for more information https://github.com/nexcess/magento-turpentine/wiki/

ESI and Gotchas

Defining ESI caching policies

All ESI caching policies should be defined in layout XML, specifically in the local.xml file of your current theme. A typical policy will appear as a method call with options passed in a parameters block.

Caching policies can be applied to new blocks or existing blocks but it should be noted that some default blocks have ESI set out of the box. These will need special configuration to override the default behaviours set by Turpentine (see the sections below).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<block type="core/template" name="my_block" template="test/mytemplate.phtml">
    <action method="setEsiOptions">
        <params>
            <scope>page</scope>
            <access>public</access>
            <ttl>100</ttl>
        </params>
    </action>
</block>

<reference name="account">
    <action method="setEsiOptions">
        <params>
            <scope>global</scope>
            <access>private</access>
            <ttl>3600</ttl>
        </params>
    </action>
</reference>

Do not nest ESI/AJAX caching policies

It is not possible to nest two ESI policies (nor does it make sense). Instead, try and separate the blocks apart and give them separate caching policies. This is common when there are many blocks in the header that all require different registry values.

The only way for all of the blocks to have the required values is to add them to the nearest ESI block, this means all the blocks will have access to those registry keys, but could mean that some data is loaded needlessly.

You have to decide what is the most efficient way to handle this in terms of performance and development time. Either splitting the blocks up and removing the parent ESI (and assigning the required keys and ESI options) or keeping every thing in one place.

Overriding default turpentine ESI policy

Some times you will want to disable the default ESI policy, to do this, add the disableEsiInjection parameter with a value of 1. You can see what the default policies are by looking at ./app/design/frontend/base/default/layout/turpentine_esi.xml.

1
2
3
4
5
6
7
8
<reference name="header">
    <action method="setEsiOptions">
        <params>
            <disableEsiInjection>1</disableEsiInjection>
            <!-- My custom ESI option overrides for this block -->
        </params>
    </action>
</reference>

Block is not loading with required data!

Varnish works by performing what is essentially an AJAX request back to a special controller that will render a layout block. This happens with both ESI and AJAX caching blocks, ESI will make the request from the server's Varnish instance to Magento and AJAX will behave like a normal AJAX call (replacing the missing hole punched block).

What is important to remember is that due to this, certain state is lost on server call that needs persisting manually from the parent page. This can include things such as the current product or category. We can handle this by telling telling Varnish to pass this along in the ESI/AJAX call.

All of this data is stored and retrieved from the standard registry Mage::registry('key') used throughout Magento.

See the section on registry_keys here for how this should work in your caching policy. https://github.com/nexcess/magento-turpentine/wiki/ESI_Cache_Policy

How do I see what is rendered in the hole punched block separately?

Turpentine allows you to enable "Debug" mode for Varnish (don't do this on production). This allows you to see what URL Varnish is calling back to to retrieve the hole punched block which is useful when trying to debug missing data from the registry.

In System/Configuration for Turpentine's Varnish options you can enable Debug Info, Varnish Command logging and Block logging. Once this is enable and caches are cleaned, you can view the HTML source to see information about where the ESI block is calling to and visit it in a web browser. This should also work with Xdebug allowing you to see what registry keys are required for your custom blocks to work correctly.