Varnish Cache pour PrestaShop : quand les modules de cache Full Page ne suffisent plus
Ce qu'est Varnish et pourquoi c'est important pour PrestaShop
Varnish Cache est un reverse proxy HTTP qui se place entre votre serveur web et Internet, servant des copies en cache des pages sans jamais toucher PHP ou MySQL. Lorsqu'un visiteur demande une page que Varnish a mise en cache, la réponse provient directement de la mémoire en quelques microsecondes. PHP ne s'exécute pas. MySQL ne reçoit aucune requête. Le serveur web remarque à peine que la requête a eu lieu.
Cela est fondamentalement différent du fonctionnement des modules de cache Full Page (FPC) basés sur PHP dans PrestaShop. Un module FPC s'exécute toujours au sein de PHP. La requête atteint Apache ou Nginx, PHP démarre, PrestaShop s'initialise (chargement de la configuration, établissement des connexions à la base de données, analyse des routes), puis le module FPC intercepte la requête avant que la logique complète du contrôleur ne s'exécute, servant un fichier HTML mis en cache. Bien que cela soit nettement plus rapide que de rendre la page à partir de zéro, cela implique toujours le démarrage de PHP et le chargement du framework PrestaShop. Cette surcharge, typiquement de 50 à 200 millisecondes même pour un cache hit, s'accumule sous charge.
Varnish élimine entièrement cette surcharge. Un cache hit Varnish est servi en 1 à 5 millisecondes. Sous un trafic élevé, la différence est spectaculaire. Une boutique PrestaShop qui peine à gérer 100 utilisateurs simultanés avec un module FPC peut servir des milliers d'utilisateurs simultanés avec Varnish, car la grande majorité des requêtes n'atteint jamais le backend PHP.
Quand les modules Full Page Cache en PHP sont suffisants
Avant d'investir dans Varnish, il est utile de comprendre quand un module FPC basé sur PHP est suffisant. Pour de nombreuses boutiques PrestaShop, c'est le cas.
Si votre boutique enregistre moins de 50 000 pages vues par jour, un module FPC bien configuré gérera la charge sans problème. La complexité supplémentaire de Varnish n'est pas justifiée lorsque votre serveur dispose de capacité de réserve. Si vos temps de réponse serveur avec le FPC sont constamment inférieurs à 200 millisecondes, vos visiteurs bénéficient déjà de chargements rapides. Le goulot d'étranglement à ce stade est probablement le rendu frontend (CSS, JavaScript, images) plutôt que le temps de réponse du serveur.
Les modules FPC gèrent également certains scénarios spécifiques à PrestaShop de manière plus élégante que Varnish, car ils fonctionnent à l'intérieur de l'application. Ils peuvent vérifier si un utilisateur est connecté, si le panier contient des articles et si certains contenus dynamiques doivent être personnalisés, le tout au sein du même processus PHP. Avec Varnish, ces vérifications doivent être gérées via l'inspection des cookies et des règles de variation du cache, ce qui ajoute de la complexité à la configuration.
Envisagez Varnish lorsque votre boutique fait régulièrement face à des pics de trafic (ventes flash, campagnes marketing, pics saisonniers) qui saturent votre capacité PHP, lorsque vous avez besoin de temps de réponse inférieurs à 10 ms pour des raisons de SEO ou d'expérience utilisateur, lorsque votre budget d'hébergement est limité et que vous devez servir plus de trafic avec le même matériel, ou lorsque votre boutique génère un ratio élevé de navigation anonyme (pages de catégories, pages de produits) par rapport à l'activité du panier et du checkout.
Comment fonctionne Varnish : le flux des requêtes
Comprendre le flux des requêtes à travers Varnish est essentiel pour le configurer correctement avec PrestaShop.
Arrivée de la requête
Lorsqu'un visiteur demande une page, la requête atteint d'abord Varnish (Varnish écoute sur le port 80 ou 443 si la terminaison est assurée par un proxy frontal). Varnish examine la requête : l'URL, la méthode HTTP, les cookies et les en-têtes.
Recherche dans le cache
Varnish vérifie son cache à la recherche d'une réponse stockée correspondant à cette requête. La clé de cache est typiquement basée sur l'URL et des en-têtes sélectionnés. Si une réponse correspondante existe et n'a pas expiré, Varnish la sert directement. C'est un cache hit. La réponse est envoyée au visiteur et le serveur backend n'est jamais contacté.
Cache miss
Si aucune réponse en cache correspondante n'existe, Varnish transmet la requête au serveur backend (Apache ou Nginx exécutant PrestaShop). PrestaShop traite la requête normalement, génère la réponse HTML et la renvoie à Varnish. Varnish stocke la réponse dans son cache (si la réponse est cacheable) et la transmet au visiteur. Les requêtes suivantes pour la même page seront servies depuis le cache.
Invalidation du cache
Lorsque les données produit changent, que les prix sont mis à jour ou que le contenu est modifié, la version en cache devient obsolète. Varnish doit être informé de supprimer l'ancienne version en cache afin d'en récupérer une nouvelle depuis le backend. C'est l'invalidation du cache, et c'est la partie la plus difficile de tout système de mise en cache à maîtriser correctement.
Configuration VCL pour PrestaShop
Le Varnish Configuration Language (VCL) est un langage dédié qui contrôle la façon dont Varnish gère les requêtes. Une configuration VCL appropriée pour PrestaShop doit prendre en compte plusieurs comportements spécifiques à PrestaShop.
Définition du backend
La définition du backend indique à Varnish où transmettre les cache misses. Pour une installation PrestaShop typique où Apache ou Nginx tourne sur le même serveur sur le port 8080 :
backend default {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 5s;
.first_byte_timeout = 60s;
.between_bytes_timeout = 10s;
}
Les timeouts sont importants. Les pages PrestaShop peuvent prendre plusieurs secondes à se générer sur un cache froid, particulièrement les pages de catégories avec de nombreux produits. Un first_byte_timeout trop bas amène Varnish à retourner une erreur 503 avant que PrestaShop n'ait fini de générer la page.
Gestion des cookies et des sessions
Les cookies représentent le plus grand défi lors de la mise en cache de PrestaShop avec Varnish. PrestaShop définit plusieurs cookies par défaut, et Varnish traite toute requête avec des cookies comme non cacheable, sauf instruction contraire. Si vous ne gérez pas les cookies dans votre VCL, Varnish ne mettra quasiment rien en cache.
PrestaShop définit ces cookies sur la plupart des requêtes : le cookie de session (typiquement nommé PrestaShop-xxxx), les cookies liés au panier, les cookies Google Analytics (_ga, _gid, _gat) et divers cookies de tracking provenant d'outils marketing. Parmi ceux-ci, seul le cookie de session PrestaShop est pertinent pour le comportement du cache. Les cookies d'analytics et de tracking doivent être supprimés de la requête avant la recherche dans le cache afin qu'ils n'empêchent pas la mise en cache.
Dans votre sous-routine VCL vcl_recv, supprimez les cookies non essentiels :
sub vcl_recv {
# Supprimer les cookies Google Analytics et autres cookies de tracking
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_ga|_gid|_gat|__utm[a-z]+|_fbp|_gcl_[a-z]+)=[^;]*", "");
# Supprimer l'en-tête cookie vide
if (req.http.Cookie ~ "^\s*$") {
unset req.http.Cookie;
}
}
Décider quoi mettre en cache
Toutes les pages PrestaShop ne doivent pas être mises en cache. Le VCL doit distinguer les requêtes cacheables des requêtes non cacheables.
Toujours mettre en cache : les pages produit pour les visiteurs anonymes, les pages de listing par catégorie, les pages CMS (à propos, conditions générales, contact), la page d'accueil, les pages fabricants et fournisseurs, les pages du sitemap.
Ne jamais mettre en cache : la page du panier, les pages de commande (toutes les étapes), l'espace compte client (commandes, adresses, informations personnelles), les pages de connexion et d'inscription, toute page pour un client connecté, les requêtes POST, les requêtes AJAX qui modifient l'état (ajout au panier, mise à jour de la quantité).
La logique VCL pour cela vérifie typiquement le chemin de l'URL et la présence de cookies de session :
sub vcl_recv {
# Ne pas mettre en cache les requêtes POST
if (req.method == "POST") {
return (pass);
}
# Ne pas mettre en cache la zone admin
if (req.url ~ "^/admin") {
return (pass);
}
# Ne pas mettre en cache le checkout et le panier
if (req.url ~ "(cart|order|login|my-account|module/)" ) {
return (pass);
}
# Ne pas mettre en cache si le client a des articles dans le panier
if (req.http.Cookie ~ "PrestaShop-") {
return (pass);
}
return (hash);
}
Définir la durée du cache
Dans la sous-routine vcl_backend_response, vous contrôlez combien de temps Varnish met chaque réponse en cache. PrestaShop envoie des en-têtes Cache-Control qui disent typiquement no-cache ou private car il suppose que chaque réponse peut contenir du contenu personnalisé. Vous devez les remplacer pour les pages que vous savez être sûres à mettre en cache :
sub vcl_backend_response {
# Mettre en cache les pages produit et catégorie pendant 1 heure
if (bereq.url ~ "^/([0-9]+-|[a-z]+-[0-9]+)") {
set beresp.ttl = 1h;
unset beresp.http.Set-Cookie;
}
# Mettre en cache les assets statiques pendant 1 jour
if (bereq.url ~ "\.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf)$") {
set beresp.ttl = 1d;
unset beresp.http.Set-Cookie;
}
}
La suppression du Set-Cookie des réponses mises en cache est critique. Si une réponse en cache inclut un en-tête Set-Cookie, Varnish ne la mettra pas en cache par défaut, et même s'il est forcé de la mettre en cache, il définirait le même cookie de session pour chaque visiteur, provoquant un détournement de session.
Invalidation du cache avec des requêtes PURGE
Lorsqu'un prix de produit change, qu'un nouveau produit est ajouté ou que du contenu est mis à jour, la version en cache doit être invalidée. Varnish supporte les requêtes PURGE : une méthode HTTP spéciale qui indique à Varnish de supprimer une URL spécifique de son cache.
Configurer le support PURGE
Ajoutez la gestion PURGE à votre VCL :
acl purge {
"127.0.0.1";
"localhost";
}
sub vcl_recv {
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return (synth(405, "Non autorisé."));
}
return (purge);
}
}
L'ACL restreint les requêtes PURGE à localhost, empêchant les utilisateurs externes de vider votre cache.
Déclencher les purges depuis PrestaShop
PrestaShop n'envoie pas de requêtes PURGE nativement. Vous avez besoin d'un module ou d'un hook personnalisé qui détecte quand un contenu cacheable change et envoie une requête PURGE à Varnish. Le module s'accroche aux événements PrestaShop comme actionProductUpdate, actionCategoryUpdate et actionCMSPageUpdate. Lorsque ces événements se déclenchent, le module envoie une requête HTTP PURGE à l'URL correspondante sur le serveur Varnish.
Pour une mise à jour de produit, le module purgerait l'URL du produit, les URLs des catégories auxquelles le produit appartient (car les pages de listing de catégories affichent les prix et la disponibilité des produits), et potentiellement la page d'accueil si elle affiche des produits mis en avant. Cette cascade de purges est nécessaire pour empêcher l'apparition de données obsolètes n'importe où sur le site.
Invalidation basée sur les bans
Pour les scénarios où de nombreuses URLs doivent être purgées en même temps (une mise à jour de prix sur tout le site, un changement de design, une nouvelle bannière promotionnelle), les requêtes PURGE individuelles sont impraticables. Varnish supporte les bans, qui sont des règles d'invalidation basées sur des motifs. Un ban indique à Varnish de supprimer tout objet en cache correspondant à un motif :
sub vcl_recv {
if (req.method == "BAN") {
if (!client.ip ~ purge) {
return (synth(405, "Non autorisé."));
}
ban("req.url ~ " + req.http.X-Ban-Pattern);
return (synth(200, "Banni."));
}
}
L'envoi d'une requête BAN avec l'en-tête X-Ban-Pattern: /category/ invaliderait toutes les pages de catégories en cache en une seule opération.
Edge Side Includes (ESI) pour les blocs dynamiques
De nombreuses pages PrestaShop contiennent un mélange de contenu statique et dynamique. Le listing de produits sur une page de catégorie est le même pour chaque visiteur, mais l'en-tête affichant le nombre d'articles dans le panier est personnalisé. Sans ESI, vous ne pouvez pas mettre la page en cache du tout car l'en-tête dynamique rend toute la réponse spécifique au visiteur.
Les Edge Side Includes résolvent ce problème en vous permettant de marquer des sections de la page comme des fragments récupérés séparément. Varnish assemble la page finale à partir de fragments en cache et non mis en cache.
Comment fonctionne ESI
Dans votre template Smarty, au lieu de rendre le widget du panier directement, vous incluez une balise ESI :
<esi:include src="/module/cartwidget/ajax" />
Lorsque Varnish traite la page en cache, il rencontre la balise ESI et effectue une requête backend séparée pour ce fragment. Le corps principal de la page est servi depuis le cache, tandis que le widget du panier est récupéré frais depuis PrestaShop. La réponse assemblée inclut à la fois le corps en cache et le widget du panier frais.
Activez le traitement ESI dans votre VCL :
sub vcl_backend_response {
set beresp.do_esi = true;
}
Considérations ESI pour PrestaShop
L'implémentation d'ESI nécessite la modification de vos templates PrestaShop pour séparer le contenu dynamique en fragments compatibles ESI. Chaque fragment a besoin de son propre point de terminaison URL qui retourne uniquement le HTML pour ce bloc. Les fragments qui sont typiquement dynamiques et nécessitent un traitement ESI incluent le widget récapitulatif du panier (nombre d'articles, total), le message de bienvenue du client ("Bonjour, Pierre"), les recommandations de produits personnalisées, le lien connexion/déconnexion et les produits récemment consultés.
L'effort requis pour implémenter correctement ESI est considérable. Chaque fragment dynamique nécessite un contrôleur dédié, les templates doivent être restructurés, et les règles de mise en cache pour chaque fragment doivent être ajustées individuellement. C'est l'une des raisons pour lesquelles Varnish est considéré comme une optimisation avancée : il fonctionne le mieux lorsque l'application a été conçue en le prenant en compte.
Vérifications de santé du backend
Varnish peut surveiller la santé de votre serveur backend et prendre des mesures lorsqu'il devient indisponible. Ceci est configuré dans la définition du backend :
backend default {
.host = "127.0.0.1";
.port = "8080";
.probe = {
.url = "/ping.php";
.timeout = 2s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
}
Varnish envoie une requête à /ping.php toutes les 5 secondes. Si 3 des 5 dernières vérifications échouent, Varnish marque le backend comme malade. Tant que le backend est malade, Varnish peut servir du contenu en cache périmé (mode grace) au lieu de retourner des erreurs aux visiteurs. Cela signifie que votre boutique reste partiellement disponible même lorsque le backend PHP tombe en panne ou redémarre.
La configuration du mode grace détermine combien de temps Varnish servira du contenu périmé :
sub vcl_backend_response {
set beresp.grace = 6h;
}
Avec un grace de 6 heures, si votre backend tombe en panne, les visiteurs verront des pages en cache (même si elles datent de 6 heures) plutôt que des pages d'erreur. Les prix des produits pourraient être légèrement obsolètes, mais la boutique reste fonctionnelle pendant que vous résolvez le problème du backend.
Benchmarks de performance
La différence de performance entre l'absence de cache, le FPC PHP et Varnish est substantielle et mesurable.
Sans cache (PrestaShop nu) : Une page produit PrestaShop typique prend 200 à 800 millisecondes à se générer, selon le matériel du serveur, le nombre de modules chargés et le nombre de requêtes à la base de données. Sous charge, les temps de réponse augmentent car les workers PHP sont saturés. Un seul serveur peut gérer 20 à 50 utilisateurs simultanés avant que les temps de réponse ne deviennent inacceptables.
Module FPC PHP : Les cache hits sont servis en 30 à 100 millisecondes car PHP démarre toujours et le framework s'initialise partiellement. Sous charge, la performance est bien meilleure car les réponses en cache nécessitent un temps de traitement PHP minimal. Un seul serveur peut gérer 200 à 500 utilisateurs simultanés selon la configuration. Les cache misses prennent toujours le temps complet de rendu.
Varnish : Les cache hits sont servis en 1 à 5 millisecondes. Sous charge, Varnish lui-même peut gérer des milliers de connexions simultanées car il est écrit en C et conçu spécifiquement pour cette charge de travail. Le serveur backend ne gère que les cache misses, qui représentent une petite fraction du trafic total sur un système correctement configuré. Le même matériel qui peine avec 50 utilisateurs simultanés sans cache peut en gérer 5 000 ou plus avec Varnish.
Ces chiffres illustrent pourquoi Varnish vaut la complexité de configuration pour les boutiques à fort trafic. L'amélioration des performances n'est pas incrémentale : c'est un ordre de grandeur.
Exigences d'hébergement
Varnish a des exigences d'hébergement spécifiques que tous les environnements d'hébergement PrestaShop ne peuvent pas satisfaire.
Accès au serveur
Vous avez besoin d'un accès root pour installer et configurer Varnish. Les plans d'hébergement mutualisé ne supportent pas Varnish car il nécessite son propre processus écoutant sur un port et interceptant tout le trafic HTTP. Vous avez besoin d'un VPS, d'un serveur dédié ou d'une instance cloud où vous contrôlez l'ensemble de la pile serveur.
Mémoire
Varnish stocke son cache en RAM. La quantité de RAM nécessaire dépend du nombre de pages uniques dans votre catalogue et de la taille de chaque réponse en cache. Une formule approximative : le nombre de pages cacheables multiplié par la taille moyenne des pages donne la taille minimale du cache. Une boutique avec 5 000 produits, 200 catégories et une taille moyenne de page de 50 Ko nécessite environ 260 Mo de RAM pour le cache. Ajoutez la surcharge pour Varnish lui-même et vous devriez allouer au moins 512 Mo. Pour les catalogues plus importants, 1 à 2 Go est courant.
Configuration des ports
Dans une configuration standard, Varnish écoute sur le port 80 (le port HTTP par défaut) et transmet les cache misses au serveur web sur un port différent (généralement 8080). Cela signifie que vous devez reconfigurer Apache ou Nginx pour écouter sur le port 8080 au lieu du 80. Si vous utilisez HTTPS (et vous devriez), vous placez typiquement Nginx devant Varnish pour gérer la terminaison SSL : Nginx sur le port 443 termine le SSL et transmet à Varnish sur le port 80, qui transmet les cache misses à Apache ou PHP-FPM sur le port 8080.
Exemple de configuration Docker
Faire tourner Varnish dans Docker aux côtés d'un conteneur PrestaShop est une manière propre d'ajouter Varnish à une installation existante sans modifier le système hôte.
Configuration Docker Compose
Une configuration Docker Compose basique avec Varnish, Nginx pour le SSL et PrestaShop :
services:
varnish:
image: varnish:7.4
ports:
- "80:80"
volumes:
- ./varnish/default.vcl:/etc/varnish/default.vcl:ro
environment:
- VARNISH_SIZE=512m
depends_on:
- prestashop
prestashop:
image: prestashop/prestashop:8
expose:
- "80"
environment:
- DB_SERVER=db
db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=secretpassword
- MYSQL_DATABASE=prestashop
Dans cette configuration, Varnish est le point d'entrée sur le port 80. Le conteneur PrestaShop n'expose pas son port à l'hôte, seulement au réseau Docker. L'hôte backend VCL serait prestashop (le nom du service Docker) sur le port 80.
VCL pour Docker
La définition du backend VCL pour Docker utilise le nom du service au lieu de localhost :
backend default {
.host = "prestashop";
.port = "80";
}
Le DNS interne de Docker résout le nom du service en IP du conteneur. Le reste de la configuration VCL reste identique à une configuration non-Docker.
Stockage du cache dans Docker
Par défaut, l'image Docker de Varnish utilise un stockage en mémoire (malloc), idéal pour les performances. La variable d'environnement VARNISH_SIZE contrôle la quantité de mémoire que Varnish alloue à son cache. Définissez cette valeur de manière à ce qu'elle tienne dans les limites de mémoire de votre conteneur tout en laissant de la place pour le processus Varnish lui-même.
Pour un cache persistant qui survit aux redémarrages du conteneur, vous pouvez utiliser un stockage basé sur des fichiers en montant un volume, mais c'est rarement nécessaire. Le cache se réchauffe rapidement (en quelques minutes après réception du trafic), et le stockage basé sur des fichiers est plus lent que le stockage en mémoire.
Surveillance des performances de Varnish
Varnish fournit des outils intégrés pour surveiller les performances du cache.
La commande varnishstat affiche des statistiques en temps réel incluant le taux de hits du cache, les connexions backend et l'utilisation de la mémoire. La métrique la plus importante est le taux de hits, qui devrait être de 85 % ou plus pour une configuration bien optimisée. Si votre taux de hits est inférieur à 70 %, révisez vos règles VCL car trop de requêtes passent au backend.
La commande varnishlog affiche des logs détaillés par requête, inestimables pour débuguer pourquoi certaines requêtes ne sont pas mises en cache. Vous pouvez filtrer par motif d'URL, code de réponse ou statut cache hit/miss.
La commande varnishtop affiche une liste classée des entrées de log les plus fréquentes, vous aidant à identifier des patterns dans les cache misses ou les erreurs.
Pièges courants
Oublier de supprimer les cookies
La mauvaise configuration Varnish la plus courante avec PrestaShop est de ne pas supprimer les cookies d'analytics et de tracking. Ces cookies sont présents sur pratiquement chaque requête et rendent chaque requête unique du point de vue de Varnish, résultant en un taux de hits de 0 %. Supprimez toujours les cookies dont vous n'avez pas besoin pour la variation du cache.
Mettre en cache du contenu personnalisé
Si votre VCL est trop agressive, elle mettra en cache des pages contenant du contenu personnalisé (message de bienvenue de l'utilisateur connecté, contenu du panier) et les servira à d'autres visiteurs. Cela cause de sérieux problèmes d'utilisabilité et des problèmes potentiels de confidentialité. Transmettez toujours les requêtes contenant des cookies de session au backend.
Pas d'invalidation lors des changements de contenu
Sans un mécanisme de purge approprié, les changements de contenu dans le back office ne seront pas visibles tant que les pages en cache n'expirent pas naturellement. Pour une boutique avec des changements d'inventaire actifs, cela signifie que les visiteurs pourraient voir des produits en rupture de stock, des prix incorrects ou des descriptions obsolètes. Implémentez le support PURGE ou BAN et intégrez-le avec les hooks de mise à jour de PrestaShop.
Ignorer HTTPS
Varnish ne gère pas nativement le SSL. Vous devez placer un proxy de terminaison SSL (Nginx, HAProxy ou un load balancer cloud) devant Varnish. Ne pas planifier cela dans votre architecture mène à des problèmes de contenu mixte, des boucles de redirection ou une incapacité à servir du trafic HTTPS.
Varnish est-il adapté à votre boutique
Varnish est un outil puissant, mais ce n'est pas le bon choix pour chaque boutique PrestaShop. Il ajoute de la complexité opérationnelle : un service supplémentaire à surveiller, un nouveau langage de configuration à apprendre, une couche supplémentaire dans votre processus de débogage. Les avantages sont clairs et mesurables pour les boutiques qui en ont besoin, mais ils ont un coût en temps de mise en place, en maintenance et en difficulté de dépannage.
Si votre boutique fait moins de 50 000 pages vues par jour et que votre serveur gère la charge confortablement avec un module FPC, Varnish est une complexité inutile. Si votre boutique fait régulièrement face à des pics de trafic qui submergent votre serveur, sert un volume élevé de trafic de navigation anonyme, ou a besoin des temps de réponse les plus rapides possibles pour le SEO ou l'expérience utilisateur, Varnish offre un niveau de performance qu'aucune solution de cache basée sur PHP ne peut égaler.
Commencez par une optimisation PrestaShop appropriée (optimisation des requêtes, audit des modules, PHP OPcache, optimisation des images) et un module FPC. Si ces optimisations ne suffisent pas, Varnish est l'étape suivante sur l'échelle de mise à l'échelle des performances.
Cette réponse vous a-t-elle été utile ?
Vous avez encore des questions ?
Can't find what you're looking for? Send us your question and we'll get back to you quickly.