Mugo Web main content.

Built-in Varnish Cache "purge-on-publish" support in eZ Publish

By: Peter Keung | May 22, 2015 | eZ Publish development tips and Site performance

eZ Publish 5 comes with built-in Varnish Cache support. Essentially this means that when content is published in the eZ Publish back-end, it notifies Varnish so that the Varnish cache is cleared. This feature is often called "purge-on-publish" and makes it so that you can cache your pages for a very long time, but that edits refresh the cache and thus appear immediately. To get this native support, you just have to use the "new stack" in eZ Publish. However, even if your legacy site is not ready to be fully upgraded to the new stack and you are running eZ Publish 5 in "legacy mode", you can take advantage of this native support.

The core part of the "purge-on-publish" feature is the "X-Location-Id" HTTP header. When eZ Publish serves up a node / location full view, it sends the "X-Location-Id" header as part of the response. This gets cached in Varnish. When content is edited in eZ Publish, it sends an instruction to Varnish to clear its cache of items containing the "X-Location-Id" header with the node / location ID value.

On an eZ Publish 5 legacy site, if you route all requests through the Symfony kernel but in "legacy mode", eZ Publish will try to clear the Varnish cache, presuming you have also properly configured the purge_servers settings. Then all you need to do is configure the eZ Publish legacy kernel to include an "X-Location-Id" header as part of its response. To do this, simply hook into the "content/view" event listener:

1. Create a PHP function to inject the "X-Location-Id" header:

<?php
class YourFunctionCollection
{
    /*
     * Injects X-Location-Id HTTP header for Varnish cache clearing purposes
     * Takes advantage of content/view listener
     * Activated in [Event] block of site.ini
     * Listeners[]=content/view@YourFunctionCollection::addXLocationIdHeader
     */
    public static function addXLocationIdHeader( int $nodeID, eZINI $siteINI )
    {
        header( 'X-Location-Id: ' . $nodeID );
        return $nodeID;
    }
}

In an override of site.ini, tell eZ Publish to run this function whenever it generates a node full view:

[Event]
Listeners[]=content/view@YourFunctionCollection::addXLocationIdHeader

Now you have "purge-on-publish" support for your eZ Publish 5 legacy site!

Extra note: in legacy mode, pure legacy responses will not get properly cached if your Varnish configuration respects the Cache-Control: private HTTP header. To fix this put the following configuration in a site.ini.append.php file for your front-end siteaccess(es):

[HTTPHeaderSettings]
# Apply the headers to module views as well as standard content views
OnlyForContent=disabled
Cache-Control[]
Cache-Control[/]=public