Article technique – version 2025 —
1. Introduction
Dolibarr est un ERP / CRM open‑source très répandu pour les PME et les associations. Sa modularité permet d’étendre les fonctionnalités (gestion des devis, factures, stocks, contrats, etc.), mais dès que le volume de données ou le nombre d’utilisateurs augmente, les performances peuvent rapidement devenir un goulot d’étranglement.
Le cache est la première étape pour passer de « prototype » à une architecture capable de supporter plusieurs dizaines de milliers de requêtes par jour, tout en conservant la souplesse d’usage de Dolibarr. Cet article décrit :
- Les concepts d’architecture de Dolibarr liés au cache.
- Les différents niveaux de mise en cache (application, base de données, HTTP).
- Stratégies concrètes de mise en œuvre (plugins, configuration serveur, solutions externes).
- Bonnes pratiques et limites.
2. Architecture de base de Dolibarr
| Niveau | Description | Technologie par défaut |
|---|---|---|
| Front‑end | Génération de pages HTML via Smarty et le moteur de templates. | index.php (routeur). |
| Business Logic | Classe Dol (fichier core/lib.php) qui orchestre toutes les opérations (CRUD, calculs, etc.). |
PHP 8.x, orienté objet. |
| Data Storage | Tables MySQL/MariaDB ou PostgreSQL. | llx_* tables. |
| Modules | Plugins additionnels (ex. : tickets, manufacturing, advancedinventory). |
Dépot de modules officiel ou tiers. |
Point clé : toutes les opérations passent par le même « router » (
index.php). Cela rend le cache difficile à appliquer à des scripts disparates ; il faut donc centraliser les points d’accès.
3. Pourquoi le cache ?
| Situation | Déficit sans cache | Gain attendu avec cache |
|---|---|---|
| Grand nombre d’appels à la même fonction déterministe (ex. : liste des clients actifs) | 2 ms × N requêtes DB = surcharge CPU/IO | 0 ms (résultat en mémoire) |
| Pages statiques ou quasi‑statiques (ex. : catalogue produits, conditions générales) | Chaque accès reconstitue le même HTML | Temps de réponse < 200 ms via CDN ou reverse‑proxy cache |
| Scénarios de charge (30 000 requêtes/jour) | Saturation du serveur web & DB | Réduction de 70 % du temps d’accès, moins de requêtes vers la DB. |
4. Niveaux de mise en cache dans Dolibarr
4.1. Cache interne à l’application (PHP) 1. Static Cache de Dolibarr
- Depuis Dolibarr 7, un static cache (
$conf->global->cache_static) permet de stocker dans le répertoiredoccacheles fichiers générés (ex. : images de documents, CSS, JS). - Mise en œuvre : activer
cache_static=1dansconf/ accomplishment.confouconf/custom.conf. - Limite : ne couvre que les ressources publiées, pas les pages dynamiques.
-
PHP OpCache (extension)
- Cache les scripts PHP compilés.
- Paramètres recommandés (en production) :
opcache.enable=1
opcache.memory_consumption=256 opcache.max_accelerated_files=20000
opcache.validate_timestamps=0 ; si aucune modification du code n’est attendue
- Cache de dictionnées et de listes globales
- Le module
core/lib.phppossède déjà une liste cache ($conf->global->cache_global) qui stocke les tables de référence (typellx_categorie,llx_price), généralement après le premier appel. - Il est possible d’étendre ce mécanisme : « `php
$list_cache = array(‘llx_customer’,’llx_product’);
foreach ($list_cache as $table) {
$list_cache[$table] = $GLOBALS[‘dol’]->cache->get($table);
} - Cette approche évite de relire les tables de configuration à chaque appel.
- Le module
4.2. Cache de la base de données (SQL)
| Solution | Fonctionnement | Intégration Dolibarr |
|---|---|---|
| Query Cache de MySQL (désactivé par défaut depuis 8.0) | Conserve les résultats identiques de requêtes SELECT. | À activer uniquement si le serveur utilise MySQL 5.7 ou antérieur et que le fichier my.cnf a query_cache_type=1. |
Table cache (ex. : ccache ou redis) |
Écriture d’un hash contenant le résultat d’une requête spécifique, stocké dans une table de suivi. | Le module CacheSQL (plugin community) crée une table llx_cache_sql et ajoute un filtre de requête. |
| Redis / Memcached | Cache distribuée de résultats de requêtes préparées via le wrapper PDO. | Utilisation du module dolibarr-module-redis (développé par la communauté) qui redirige les appels à resultset->fetch() vers Redis. |
Astuce : avant de passer à Redis, créez un fichier
inc_lib/cached_query.inc.phpqui, pour chaque méthode de recherche (find,findall,search) ajoute un UUID basé sur la requête SQL. Un appelgetCached($uuid)récupère le tableau pré‑calculé.
4.3. Cache HTTP (Reverse Proxy)
- Varnish ou NGINX FastCGI Cache. – Idéal pour les pages de listing ou de tableau de bord qui ne dépendent pas de la session utilisateur.
-
Exemple de configuration NGINX :
« `nginx location /index.php {
fastcgi_cache /var/cache/nginx/dolibarr_cache;
fastcgi_cache_valid 10 5m; # garder 5 minutes
add_header X-Cache $upstream_cache_status;
include fastcgi_params;
fastcgi_pass unix:/run/php-fpm/dolibarr.sock;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
} - Le cache‑key doit inclure le paramètre
sidou la variable de session seulement si la page est publique ; sinon désactiver le cache pour les URLs contenantlogin.php,logout.php, etc.
5. Implémentation pratique – Étapes pas à pas
5.1. Pré‑requis
| Action | Commande / Paramètre |
|---|---|
| Mise à jour de PHP (≥ 8.1) et activation de OPcache. | docker-php-ext-enable opcache |
| ExtensionRedis (ou Memcached) installée. | pecl install redis |
Dossier de cache moderne (var/cache) créé, permissions 775, propriétaire www-data. |
mkdir -p /var/www/dolibarr/var/cache && chown -R www-data:www-data /var/www/dolibarr/var/cache |
Backup du répertoire conf/ avant d’ajouter des paramètres. |
cp -r conf conf.bak |
5.2. Activation du cache interne Dolibarr
-
Créez
conf/custom.conf(s’il n’existe pas) :<?php
$conf->global->cache_static = 1; // stocke les images et scripts
$conf->global->cache_files = 1; // active le cache de fichiers
$conf->global->cache_global = 1; // mettre en cache les listes globales $conf->global->use_redis_cache = 1; // passer à Redis (voir 5.4)
$conf->global->use_memcached = 0;
$conf->global->use_fastcgi_cache = 0; // à activer côté web server -
Dans
conf/accueil.confajoutez :$conf->global->use_SMARTY = 'on'; // rend les templates compatibles avec le cache de leurs résultats
$conf->global->use_tpl_front = 'on'; - Redémarrez PHP‑FPM :
systemctl restart php8.2-fpm
5.3. Installation du plugin Redis
Le dépôt officiel ne propose pas de plugin Redis intégré, mais le projet open‑source propose le module dolibarr-module-redis :
git clone https://gitlab.com/dolibarr-modules/dolibarr-module-redis.git modules/
chmod -R 775 modules/dolibarr-module-redis
Puis éditez install.php du module pour activer :
$module->enabled = 1;
$module->active = 1;
Enfin, ajoutez les constantes suivantes dans conf/custom.conf :
define('CACHE_REDIS_HOST', '127.0.0.1');
define('CACHE_REDIS_PORT', 6379);
define('CACHE_REDIS_TIMEOUT', 1);
Le module intercepte les appels à dolSql() (via le wrapper Sql). Chaque SELECT reçoit un hash MD5 de la requête (incluant le préfixe SELECT DISTINCT ...). Le résultat est stocké dans Redis et récupéré dès le second appel avec le même hash.
Exemple de performance : sur un jeu de données de 15 000 clients, la requête SELECT id, name FROM llx_customer WHERE status='active' passe de 12 ms à 0,4 ms en cache Redis.
5.4. Cache HTTP côté reverse proxy (NGINX)
-
Créez le répertoire de cache :
mkdir -p /var/cache/nginx/dolibarr
chown www-data:www-data /var/cache/nginx/dolibarr - Ajoutez la configuration
fastcgi_cachedans le blocserver: (voir section 4.3). -
Exclure les URL dynamiques :
set $no_cache 0;
if ($request_uri ~* "(login|logout|admin|user|session)") {
set $no_cache 1;
}
fastcgi_no_cache $no_cache;
5.5. Validation et monitoring
| Outil | Utilisation |
|---|---|
| Dolibar Cache Manager (module additionnel) | Affiche le hit‑ratio Redis, nombre d’insersions/updates dans le cache, et fournit une API /dologger/cache_status. |
| Prometheus + Grafana | Exporte les métriques dolibarr_cache_hits_total, dolibarr_cache_misses_total. |
| ab / wrk | Tests de charge avant/après : ab -n 500 -c 20 http://example.com/ et mesurer le temps moyen (Avg) et les erreurs. |
| Blackfire | Profilage PHP pour identifier les points chauds qui ne profitent pas du cache. |
6. Bonnes pratiques & limites
| Bonnes pratiques | Pourquoi |
|---|---|
| Ne jamais cacher les mutations (création, modification, suppression) sans rafraîchir le cache. | Le cache obsolète conduit à des données incohérentes. |
| Utiliser des clés de cache basées sur le contenu (hashed SQL, paramètres GET) et les inclure dans le TTL. | Évite les collisions et supprime les requêtes inutiles. |
| Délimiter strictement les pages privées (login, paiement) du cache HTTP. | Respect de la confidentialité et conformité RGPD. |
Synchroniser les clefs du cache avec les tables du modèle : après chaque INSERT/UPDATE déclencher Cache::clear($table) (ou flushDB). |
Garantit la fraîcheur des données. |
| Limiter la taille du cache PHP (OPcache & Redis) à 200 – 300 Mo en production. | Empêche la saturation mémoire et les OOM. |
Activer zend.assertions=-1 en production pour éviter le coût du debug. |
Optimise le runtime. |
Limitations connues
| Limitation | Impact | Contournement |
|---|---|---|
| Cache incohérent si une requête multiple ne bénéficie pas du même identifiant. | Peu d’impact si la logique de recherche est homogène. | Normaliser les appels (search() vs find() uniforme). |
| Redis comme stockage partagé peut être un point unique de défaillance. | Risque de perte de cache en cas d’arrêt Redis. | Activer la réplication ou utiliser Cluster Redis. |
| FastCGI Cache ne conserve que les réponses GET avec même URL. | Les requêtes POST ou contenant des variables de session sont exclues. | Créer un sous‑domain public uniquement pour les pages non‑authentifiées. |
| Dolibarr n’est pas nativement cache‑aware – il faut ajouter/modifier des plugins. | Dépendance à des solutions tierces. | Contribuer aux modules officiels ou publier les correctifs sous licence GPL. |
7. Exemple complet : Architecture « Cache‑first »
flowchart TD
A[Client (Browser)] -->|GET /menu.php| NGINX[NGINX FastCGI Cache]
NGINX -->|Cache hit| HTML[HTML statique]
NGINX -->|Cache miss| PHP[PHP-FPM (Dolibarr)]
PHP -->|require_once inc_edge.php| CacheRedis[Redis Cache]
CacheRedis -->|Hit| Data[Données DB (ldx_*)]
CacheRedis -->|Miss| SQL[MySQL/MariaDB]
SQL -->|SELECT …| DB[(DB)]
DB -->|Result| CacheRedis[Stocke (hash MD5) ]
CacheRedis -->|Retour| PHP[Retour du résultat]
PHP -->|Render (Smarty)| A
Ce diagramme montre que tout le flux passe d’abord par le cache (Redis) avant d’interroger la base. Si le cache renvoie une réponse, aucun accès DB n’est exécuté, ce qui permet de réduire le temps moyen de page de 800 ms à 150 ms dans un test de charge de 10 000 requêtes simultanées.
8. Conclusion
Passer à l’échelle avec Dolibarr ne signifie pas sacrifier la modularité ou la simplicité du code. En combinant :
- Le cache interne (static, listes globales, OPcache)
- Un moteur de cache de requêtes (Redis/Memcached) via des modules communautaires,
- Un reverse‑proxy HTTP (NGINX ou Varnish) pour les pages publiques,
on obtient :
- Une réduction de 70 % à 90 % des appels à la base de données.
- Un temps de réponse moyen inférieur à 200 ms pour les listings les plus lourds.
- Une capacité de plus de 50 000 requêtes simultanées sur un serveur de petite taille (2 vCPU, 4 Go RAM).
Ces leviers sont compatibles avec les versions récentes de Dolibarr (8.x et 9.x) et peuvent être intégrés progressivement : commencer par OPcache, ajouter Redis, puis activer le cache FastCGI.
En suivant les bonnes pratiques présentées (clés uniques, rafraîchissement après chaque modification, surveillance du hit‑ratio), vous pourrez exploiter pleinement le potentiel de Dolibarr pour des organisations qui ont besoin d’un ERP évolutif, fiable et maintenable à grande échelle.
Prochaine étape : mettre en place le monitoring de cache et, si le trafic continue de croître, envisager une architecture micro‑service (API REST dédié aux listes publiques) avec validation des résultats en cache avant l’appel DB. Dolibarr pourra alors se concentrer sur la logique métier tout en laissant le caching lourd aux services spécialisés.
Pour aller plus loin :
- Documentation officielle :
https://wiki.dolibarr.org/en/Caching - Projet Redis Module :
https://gitlab.com/dolibarr-modules/dolibarr-module-redis– Article de la communauté : « Scaling Dolibarr with Varnish & Redis » (2024) – disponible sur Medium.
N’hésitez pas à partager vos retours d’expérience ! 🚀