Server Setup

Deployment and cache purge on Citrus powered servers

by , , revisited on


We have by far the largest RPM repository with dynamic stable NGINX modules and VMODs for Varnish 4.1 and 6.0 LTS. If you want to install NGINX, Varnish, and lots of useful modules for them, this is your one-stop repository to get all performance-related software.
You have to maintain an active subscription in order to be able to use the repository!

Citrus is what we internally call the web software stack of Varnish, Nginx, PHP-FPM and Percona MySQL.

To invalidate PHP OPcache, without restarting PHP-FPM, you want to use cachetool.
The latest branch of cachetool only supports the most recent PHP versions.

Branch 3.x of cachetool supports many PHP versions (5.5 onward, including PHP 7).
To install it:

sudo yum -y install https://extras.getpagespeed.com/release-latest.rpm
sudo yum -y install cachetool

Often times, due to a number of caching layers, the changes to website files do not reflect on the site immediately or do not reflect at all. This is a good thing, aimed to ease the load to PHP backend and increase performance and total traffic throughput.

The caching layers may include:

  • PHP opcode cache. The production setting for revalidate_timestamps will cause old versions of PHP files to be in use until a call to opcache_reset()
  • Varnish cache. Varnish cache will store PHP-generated HTML. Supporting CMS (WordPress, Magento) will automatically communicate with Varnish in order to invalidate its cache. In some scenarios though (themes files changes) a manual cache purge is required

A simple GitHub hook for deployment and cache clearing may look like this:

<?php

// Github will post secret code to your hook script and we have to check for it
if (!isset($_GET['code']) && $_GET['code'] != 'replace-me-with-random-password') {
        exit('404');
}

$result = exec('git pull') 
        . exec('../artisan migrate') 
        . exec('cd ../ && composer install') 
        . exec('curl -X PURGE -H "User-Agent: W3 Total Cache/.*" http://www.example.com/.*')   
        . opcache_reset()
        . clearstatcache(true);

Script logic

git pull fetches files from remote git origin.

../artisan migrate runs database migrations for Laravel website.

cd ../ && composer install for a site using Composer and not tracking track vendor directory in git, install PHP libraries

curl -X PURGE -H "User-Agent: W3 Total Cache/.*" http://www.example.com/.*' This will purge complete cache for domain in Varnish

clearstatcache(true) clears real path PHP cache

Finally, opcache_reset() clears PHP opcode cache

Some things are important to remember:

The URL in Varnish cache purge should be plain HTTP, not HTTPS since communication to Varnish always happens over HTTP.
The call to opcache_reset() should only be done in a webhook and not directly on the command line. Calling it directly on the command line will not affect opcache data of PHP-FPM pools and thus the cache will stay intact.

If you want to clear PHP opcache and realpath caches on the command line, use the following:

/usr/local/bin/cachetool opcache:reset
/usr/local/bin/cachetool stat:clear

For a complete integration, take a look at GitHook.

Purge cache in Prestashop

<?php

chdir(dirname(__FILE__));

echo 'Clearing File Cache' . '<br />';
shell_exec('rm -rf ./cache/cachefs');

echo 'Clearing Smarty Caches' . '<br />';
shell_exec('rm -rf ./cache/smarty/cache');
shell_exec('rm -rf ./cache/smarty/compile');
shell_exec('rm -rf ./cache/class_index.php');

echo 'Clearing filestat cache' . '<br />';
clearstatcache();
clearstatcache(true);

echo 'Clearing PHP files cache (opcache)' . '<br />';
opcache_reset(); 

require_once 'config/settings.inc.php';

echo 'Clearing smarty cache database tables' . '<br />';

/* Connect to a MySQL database using driver invocation */
$dsn = 'mysql:dbname=' . _DB_NAME_ . ';host=' . _DB_SERVER_;

try {
    $conn = new PDO($dsn, _DB_USER_, _DB_PASSWD_);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

$conn->query(sprintf("TRUNCATE TABLE %ssmarty_cache", _DB_PREFIX_));
$conn->query(sprintf("TRUNCATE TABLE %ssmarty_last_flush", _DB_PREFIX_));
$conn->query(sprintf("TRUNCATE TABLE %ssmarty_lazy_cache", _DB_PREFIX_));

echo 'Done';

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.