Mettre en cache les pages avec Varnish et WP Fastest Cache

WP Fastest Cache fait partie des plugins WordPress de cache qui désactivent le cache navigateur sur les pages HTML. Ceci a pour conséquence de désactiver également la mise en cache de ces pages sur Varnish. Voici comment résoudre le problème.

Pourquoi les plugins WordPress désactivent le cache navigateur des pages HTML ?

WP Fastest Cache n’est pas le seul à le faire. Selon les plugins, la manipulation des headers Expires, Cache-Control et autres leur permettent de forcer le navigateur à faire une requête HTTP au serveur, et ainsi éviter que le navigateur ait des données obsolètes.

Cependant, puisque Varnish utilise aussi ces en-têtes HTTP pour prendre des décisions de mise en cache, cela désactive systématiquement le cache Varnish en marquant ces requêtes comme « uncacheable ».

En plus, les plugins comme WP Fastest Cache intègrent un mécanisme de purge de Varnish, ce qui permet donc de supprimer immédiatement les données de cache obsolètes sur Varnish, sans attendre que le cache expire.

Comment forcer la mise en cache ?

Il faut décomposer le problème en deux. D’abord, il faut marquer les réponses HTTP concernées pour éviter qu’on puisse forcer la mise en cache partout. Cela se fera au niveau d’Apache. Ensuite, il faudra détecter ce marquage au niveau de Varnish pour forcer la mise en cache.

Marquer les réponses HTTP servis depuis le cache WP Fastest Cache

WP Fastest Cache utilise mod_rewrite pour réécrire les URL vers les fichiers HTML préenregistrés dans le cache. Cela tombe bien, Apache sait ajouter des en-têtes HTTP selon la correspondance de dossier.

Dans votre VirtualHost (typiquement dans /etc/apache2/sites-available/domaine.com), ajoutez la directive suivante pour ajouter un header aux réponses servies depuis le dossier de cache de WP Fastest Cache :

<Directory ~ "wp\-content\/cache\/all(\/.*)*\/index\.html$">
    Header set Edge-Cache-Platform "wpfastestcache"
</Directory>

Redémarrez Apache ensuite :

systemctl restart apache2

À partir de ce moment, si vous faites une requête HTTP sur votre site et que la réponse est en cache par WP Fastest Cache, vous pourriez voir l’en-tête « Edge-Cache-Platform » (que vous pouvez d’ailleurs ajuster avec un autre nom, si vous souhaitez) :

$ curl -I http://www.exemple.com
HTTP/2 200
date: Sat, 01 Jun 2024 08:21:04 GMT
content-type: text/html; charset=UTF-8
server: nginx
vary: User-Agent,Accept-Encoding
last-modified: Fri, 31 May 2024 09:16:26 GMT
edge-cache-platform: wpfastestcache
cache-control: max-age=0, no-cache, no-store, must-revalidate
pragma: no-cache
expires: Mon, 29 Oct 1923 20:30:00 GMT
age: 0
accept-ranges: bytes
edge-cache-status: MISS

Détecter le marquage et appliquer les caches

Maintenant, dans votre VCL, ajoutez ceci dans la subroutine vcl_backend_response :

sub vcl_backend_response {
    if (beresp.ttl < 86400s && beresp.http.Content-Type ~ "text/html" && beresp.http.Edge-Cache-Platform ~ "wpfastestcache") {
        set beresp.ttl = 86400s;
        set beresp.grace = 86400s;
        return(deliver);
    }
}

Ceci détecte le header et le TTL (durée de validité du cache), et force celui-ci à 86 400 secondes (une journée) si elle est intérieure.

Notez également la présence de return(deliver), celui-ci est en place afin que le built-in VCL de Varnish n’entre pas en action si la requête correspond aux conditions du if. En effet, le built-in VCL va réajuster le TTL à 120s et le beresp.uncacheable = true si elle est exécutée, à cause des headers Cache-Control et autres.

Maintenant, la requête est bien mis en cache :

$ curl -I http://www.exemple.com
HTTP/2 200
date: Sat, 01 Jun 2024 08:26:04 GMT
content-type: text/html; charset=UTF-8
content-length: 85497
server: nginx
vary: User-Agent,Accept-Encoding
last-modified: Fri, 31 May 2024 09:16:26 GMT
edge-cache-platform: wpfastestcache
cache-control: max-age=0, no-cache, no-store, must-revalidate
pragma: no-cache
expires: Mon, 29 Oct 1923 20:30:00 GMT
age: 300
accept-ranges: bytes
edge-cache-status: HIT

Vous pouvez éventuellement décider de supprimer l’en-tête de réponse HTTP Edge-Cache-Platform au niveau de Varnish dans le if précédemment proposé, si vous souhaitez que cette information ne soit pas publique.

Laisser un commentaire