Dolibarr en production : DevOps et bonnes pratiques sans casser l’existant

Comment moderniser le déploiement, la maintenance et l’évolution de Dolibarr tout en préservant les processus déjà en place.


1. Pourquoi parler de DevOps pour Dolibarr ?

Dolibarr est un ERP/PGI (Gestionnaire de Entreprise) léger, écrit en PHP, qui s’installe généralement sur un serveur LAMP/LNMP.
Dans la plupart des PME :

Situation actuelle Problèmes récurrents
Installation manuelle sur un serveur dédié ou partagé Consommation d’erreurs lors des mises à jour, manque de restauration rapide, absence de monitoring
Mise à jour ponctuelle (copy‑files) Risque de ruptures de API, incompatibilités entre.modules
Sauvegarde « au pif » sur un disque externe Pas de test de restauration, perte de données en cas de corruption
Aucun contrôle de version des personnalisations Impossible de revenir à une configuration fonctionnelle

Ces limites contradisent les objectifs d’une vraie stratégie DevOps : automatisation, traçabilité, continuité de service et résilience. Le défi consiste donc à introduire des pratiques DevOps sans casser l’existant, c’est‑à‑dire en préservant le fonctionnement actuel tout en l’améliorant progressivement.


2. Une feuille de route « progressive »

Étape Objectif principal Risque de rupture Méthode de mitigation
0. Audit & Cartographie Recenser l’infrastructure, les dépendances et les points de personnalisation. Aucun Utiliser des scripts d’inventaire (Ansible, Bash) et documenter chaque customisation.
1. Gestion de la version & CI Mettre en place un dépôt Git, versionner les modifications de codage et de configuration. Perte de la brancherie existante si on force un merge immédiat. Commencer par une branche dev isolée ; les changes non‑critique restent là avant production.
2. Containerisation Emballer Dolibarr dans un conteneur Docker et déployer via Docker‑Compose/Kubernetes. Le démarrage du conteneur peut échouer sur un serveur non‑conforme. Déployer d’abord en mode “compatibility‑mode” : volume partagé avec le répertoire actuel, même docker run‑options.
3. Pipeline CI/CD Automatiser les tests unitaires (PHPUnit), les scans de sécurité (Trivy, OWASP‑ZAP) et le build d’image. Tests trop stricts qui bloquent des changements légitimes. Configurer des seuils souples au départ (ex. warning au lieu d’échec).
4. Stratégie de Déploiement Bleu/Vert Publier la nouvelle version dans un conteneur “Vert” pendant que le “Bleu” continue à servir le trafic. Incompatibilité de schéma de base de données. Utiliser des scripts de migration non‑destructifs, tester la migration sur une copie de prod.
5. Rollback automatisé Ability to revert instantly to the previous container image. Si le rollback échoue, service indisponible. Garder les images passées en local et config piggy‑back de “deploy‑previous”.
6. Monitoring & Alertes Installer Prometheus + Grafana + Alertmanager, monitorer CPU, mémoire, latence HTTP, état de la DB. Fausse‑positive qui déclenche un incident inutile. Créer des seuils conservateurs et ajouter de la « debounce » (retard).
7. Sauvegarde automatisée & Test de restauration Cron‑job de backup avec pg_dump/mysqldump + sauvegarde des dossiers /dolibarr (customisations, pièces jointes). Backup corrompu → perte de données. Tester chaque semaine la restauration sur une VM de test.
8. Documentation & Runbooks Formaliser chaque procédure (upgrade, backup, rollback). Oublis de étapes critiques en cas d’incident. Mettre à jour le wiki interne après chaque sprint.

Bottom line : chaque étape fournit des livrables concrets (ex. dépôt Git, image Docker) qui peuvent être adoptés indépendamment du niveau de maturité DevOps de l’organisation.


3. 1️⃣ Cartographier l’existant – « lorsqu’on ne veut pas tout casser »

  1. Inventaire des hôtes
    # Ansible playbook simplifié   - hosts: dolibarr-srv     tasks:
    - name: Collecter version apache, php, db
    command: "{{ item }}"
    loop: "{{ [ 'apache2ctl -v', 'php -v', 'mysql --version' ] }}"
    register: result
    - name: Write inventory report copy: content={{ result.stdout }} dest=/tmp/inventaire.txt
  2. Liste des modifications

    • Fichiers personnalisés (/dolibarr/custom/, .htaccess, scripts cron). – Extensions tierces installées (/dolibarr/business/devices/...).
    • Paramètres de configuration (conf.php, llx_catalog_prices, ldap.conf).

  3. État de la base de données

    • Exporter le schéma (mysqldump -d) et le contenu (mysqldump), sauvegarder sous version‑contrôle.

Bonne pratique : après cette première étape, créez un environnement de test clone (VM ou conteneur) où vous restaurerez exactement cet état. Toute évolution future devra d’abord passer par ce même environnement.


4. 2️⃣ Versionner le code & la configuration

4.1. Dépôt Git minimal « `bash

git init /opt/dolibarr
cd /opt/dolibarrgit add -A
git commit -m "Initial import of production snapshot"
git branch dev # branche de travail
git branch production # état actuel, immuable


- **`.gitignore`** : ne pas versionner les pièces jointes (`/upload`) et les logs temporaires.
- **LFS** (Large File Storage) pour les documents volumineux (PDF scannés, factures).
### 4.2. Gestion des configs
Utilisez **`phpdotenv`** ou le système de configuration intégré de Dolibarr pour externaliser les variables sensibles (login DB, clefs API). Exemple de `.env` :
```dotenv
DB_HOST=db-prod.mydomain.local
DB_USER=dolibarr
DB_PASSWORD=**********
APP_URL=https://erp.mondomaine.local

Astuce : placez ce fichier hors du dépôt (ex. /opt/dolibarr/.env) et injectez‑le via le mécanisme Docker --env-file.


5. 3️⃣ Containeriser Dolibarr (sans interrompre le service)

5.1. Dockerfile léger

FROM php:8.2-fpm-alpine
# Dépendances système
RUN apk add --no-cache \
gcc \
postgresql-dev \
curl \
git \
unzip \
libzip-dev \
libpng-dev \
autoconf \
automake \
libtool \
sqlite-dev
# Extensions PHP
RUN docker-php-ext-install zip pdo_mysql mbstring
RUN pecl install apcu && docker-php-ext-enable apcu
# Extension pour la lecture de PDF (optionnel)
RUN apk add --no-cache poppler-utils
# Téléchargement de Dolibarr (version LTS)
ENV DOLIBARR_VERSION=23.0.1
WORKDIR /var/www
RUN curl -L https://github.com/Dolibarr/dolibarr/releases/download/${DOLIBARR_VERSION}/dolibarr-${DOLIBARR_VERSION}.tgz | tar xz && \
mv dolibarr-${DOLIBARR_VERSION} dolibarr && \
chmod -R 775 /var/www/dolibarr && \
chown -R www-data:www-data /var/www/dolibarr
VOLUME ["/var/www/dolibarr/htdocs", "/var/www/dolibarr/files", "/var/www/dolibarr/config"]
EXPOSE 80 443USER www-data
CMD ["php-fpm"]

5.2. Docker‑Compose de base (compatible avec l’ancien serveur)

version: "3.9"
services:
web:
build: .
container_name: dolibarr_web restart: unless-stopped
ports:
- "8080:80" # expose sur le port 8080 du serveur
volumes:
# Mapping des dossiers déjà présents sur le serveur
- /opt/dolibarr/htdocs:/var/www/dolibarr/htdocs:rw
- /opt/dolibarr/files:/var/www/dolibarr/files:rw
- /opt/dolibarr/config/.env:/var/www/dolibarr/.env:ro
environment:
- PHP_MEMORY_LIMIT=256M
depends_on:
- db db:
image: mariadb:10.11
restart: unless-stopped
container_name: dolibarr_db
environment:
MYSQL_ROOT_PASSWORD: secret_root
MYSQL_DATABASE: dolibarr
MYSQL_USER: dolibarr
MYSQL_PASSWORD: secret_user
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:

Pourquoi cela ne « casse » pas l’existant ?

  • Les volumes sont monteés sur les chemins déjà occupés par l’instance actuelle.
  • En démarrant le conteneur avec --restart=unless-stopped, il se récupère automatiquement si le serveur redémarre, sans toucher aux fichiers du système hôte. – On garde la possibilité d’arrêter le service Apache/Nginx et de basculer le reverse‑proxy vers le conteneur quand on veut migrer réellement.


6. 4️⃣ CI/CD automatisé – Tests, Build & Déploiement

6.1. PHPUnit (unit tests)

« `php// tests/Dolibarr/CoreTest.phpclass CoreTest extends \PHPUnit\Framework\TestCase
{
public function testVersion()
{
$this->assertStringContainsString(‘Dolibarr’, Dolibarr::version());
}
}


- Ajoutez le fichier `phpunit.xml` avec les règles de couverture.
- Intégrez‑le au pipeline GitHub Actions, GitLab CI ou un serveur Jenkins interne.
### 6.2. Scan de sécurité
```yaml
# .github/workflows/security.yml
name: Scan sécurité
on: [push, pull_request]
jobs:
trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Trivy scan
uses: aquasecurity/trivy-action@v0.9.1
with:
image-ref: "myrepo/dolibarr:${{ github.sha }}"
format: "sarif"
exit-code: "1"
ignore-unfixed: true

Bonne pratique : Commencez par ignorer les warnings et ne bloquez que les vulnérabilités critiques.

6.3. Build d’image & push

docker build -t myrepo/dolibarr:${TAG} .
docker push myrepo/dolibarr:${TAG}

  • Utilisez le tag latest seulement sur un environnement de test, jamais en production directe.
  • Versionnez les tags selon le Semantic Versioning (v23.1.0, v23.2.0-alpha).


7. 5️⃣ Stratégie de déploiement sans interruption

7.1. Blue/Green (Bleu = prod actuelle, Vert = nouvelle version)

Action Commande (Docker‑Compose) Résultat
Arrêter le conteneur bleu docker-compose -f compose.blue.yml up -ddocker-compose -f compose.blue.yml down Service旧 version retiré
Lancer le conteneur vert docker-compose -f compose.green.yml up -d Nouvelle version prête
Test de santé curl -sSf http://localhost/status200 OK Check d‑API/DB
Basculement du reverse‑proxy Modifier le fichier default.conf du load‑balancer Nginx et recharger Le trafic passe au vert

Note : Le fichier compose.green.yml ne change que le tag d’image et les éventuels volumes persistant.

7.2. Rollback instantané

  • Le docker-compose garde la version précédente de l’image dans le registre du serveur (docker images).
  • En cas d’échec du health‑check, exécutez :
    docker-compose -f compose.green.yml down
    docker-compose -f compose.blue.yml up -d
  • Le basculement via le reverse‑proxy se fait en moins de 5 s, donc aucune interruption visible pour les utilisateurs.


8. 6️⃣ Sauvegarde, restauration et test de restauration

8.1. Backup automatisé (cron)

« `bash#!/bin/bash

TIMESTAMP=$(date +%Y%m%d-%H%M)
DB_NAME="dolibarr"
BACKUP_DIR="/var/backups/dolibarr"

mkdir -p ${BACKUP_DIR}/${TIMESTAMP}
mkdir -p ${BACKUP_DIR}/${TIMESTAMP}/db
mkdir -p ${BACKUP_DIR}/${TIMESTAMP}/files

mysqldump -u dolibarr -p$MYSQL_PASSWORD ${DB_NAME} > ${BACKUP_DIR}/${TIMESTAMP}/db/${DB_NAME}.sql

tar czf ${BACKUP_DIR}/${TIMESTAMP}/config.tar.gz /opt/dolibarr/config

tar czf ${BACKUP_DIR}/${TIMESTAMP}/dolibarr_full.tar.gz -C /opt d

find ${BACKUP_DIR} -maxdepth 1 -mindepth 1 -mtime +30 -exec rm -rf {} \;


### 8.2. Test de restauration (emploi d’une VM de test)
```bash
# 1) Créer un conteneur MySQL vide
docker run -d --name test-db -e MYSQL_ROOT_PASSWORD=root mysql:10.11
# 2) Restaurer le dump
cat backup_20251102-1230/db/dolibarr.sql | docker exec -i test-db mysql -u dolibarr -p$MYSQL_PASSWORD dolibarr
# 3) Déployer le conteneur web basé sur l’image sauvegardée
docker run -d -p 8080:80 --env-file backup_20251102-1230/.env \
-v /path/to/backup_20251102-1230/files:/var/www/dolibarr/files \
myrepo/dolibarr:23.0.1

Règle d’or : au moins une fois par mois, lancez ce scénario dans une machine CI afin de valider que le restore fonctionne sans intervention humaine.


7️⃣ Monitoring, alertes et amélioration continue

7.1. Métriques essentielles (Prometheus)

Métrique Canal Seuil d’alerte (exemple)
http_requests_total Nginx > 5000 pendant 5 min
container_cpu_usage_seconds_total Docker > 80% pendant 5 min
db_connections_active MariaDB > 150
disk_space_used_bytes (log) Filesystem < 10% restant

# prometheus.yml snip
- job_name: 'dolibarr'
static_configs:
- targets: ['dolibarr_web:80']
metrics_path: '/metrics'
scheme: http

7.2. Alertmanager (notification)

  • Email : alertmanager@example.com
  • Slack : webhook #dolibarr-incident
  • Includez le run‑book (procédure de rollback) dans la notification.

Astuce : Ajoutez un paramètre maintenance_window dans le label de chaque alerte pour éviter les fausses alertes pendant les déploiements prévus.


8️⃣ Checklist de bonnes pratiques « sans casser l’existant »

Action Pourquoi
1 Documenter chaque personnalisation (module, fichier, script). Permet de les répliquer dans les conteneurs et d’éviter les surprises.
2 Versionner le code avant toute modification. Revenir en arrière en un git revert.
3 Faire d’abord les tests dans un environnement clone. Garantie que le changement n’impacte pas la prod.
4 Utiliser des migrations de base de données non‑destructives (ex. ALTER TABLE … ADD COLUMN IF NOT EXISTS). Pas de perte de données si le schema change inattendument.
5 Mettre en place un processus de « green‑deployment » avant de toucher le bleu. Test de charge/validation en production sans impact.
6 Conserver les images précédentes (docker image prune -a désactivé, docker tag versionnée). Rollback instantané.
7 Planifier des sauvegardes + tests de restauration mensuels. Confiance que les backups sont viables.
8 Limiter les changements critiques à un Sprint (max 2 semaines) pour garder la fenêtre de validation courte. Réduction du temps de régression.
9 Automatiser la mise à jour des dépendances (Composer, plugins) via Dependabot ou Renovate. Sécurité et compatibilité assurées.
10 Faire du monitoring du temps de réponse (latence < 200 ms) et alerter dès dépassement. Détection précoce de problèmes de performance.


9️⃣ Exemple de mise en production pas à pas

  1. Pré‑préparation
    git clone https://git.mycompany.com/dolibarr-prod.git /opt/dolibarr
    cd /opt/dolibarr
    git checkout production cp .env.example .env
  2. Création d’un conteneur de test

    docker compose -f compose.test.yml up -d
    # → DB & Web démarrent, test HTTP → 200 OK ```
  3. Exécution du pipeline CI

    • git push → déclenche GitHub Action → run PHPUnitbuild imagepush sur registry.
    • Après succès, créer un tag v23.1.2-test.
  4. Déploiement bleu (production actuelle)

    • docker compose -f compose.blue.yml pull && docker compose -f compose.blue.yml up -d
    • Le service reste lancé sur le port 8080.
  5. Déploiement vert (nouvelle version)

    • Modifier compose.green.yml pour référencer myrepo/dolibarr:v23.1.2-test.
    • docker compose -f compose.green.yml up -d
    • Attendre que curl -s http://localhost/htdocs/ renvoie la nouvelle version.
  6. Vérifications

    • Test de connexion DB (mysqladmin ping).
    • Exécution d’un script de validation automatisé (php scripts/healthcheck.php).
  7. Basculement du reverse‑proxy
    location / {
    proxy_pass http://127.0.0.1:8081; # green service
    proxy_set_header Host $host;
    }

    • Reload Nginx → trafic passe au vert.
  8. Monitoring – vérifier que les métriques restent sous les seuils.
  9. Rollback (si besoin)

    • docker compose -f compose.green.yml down
    • docker compose -f compose.blue.yml up -d
    • Re‑apply le proxy vers le blue.


10️⃣ Conclusion

Adopter le DevOps pour Dolibarr ne consiste pas à remplacer l’existant du jour au lendemain, mais à injecter progressivement des mécanismes d’automatisation, de traçabilité et de résilience qui protègent l’infrastructure déjà mise en œuvre.

  • Cartographier le système actuel vous donne une visibilité complète.
  • Versionner le code et les configurations crée une base solide pour chaque évolution.
  • Containeriser permet de garder les chemins de fichiers existants tout en y ajoutant la portabilité.
  • CI/CD assure que chaque changement est testé, sécurisé et traçable avant d’atteindre la production.
  • Blue/Green et Rollback offrent la garantie d’une disponibilité continue. – Sauvegardes + restauration testée protège vos données.
  • Monitoring vous alerte dès qu’un indicateur dévie, vous permettant d’intervenir avant que le client ne le remarque.

En suivant la feuille de route décrite ci‑dessus, vous pouvez améliorer la maturité DevOps de votre environnement Dolibarr tout en conservant le service avec la même fiabilité que vous aviez aujourd’hui. > « Ne changez jamais un système qui fonctionne » – mais vous pouvez l’améliorer de façon contrôlée, réversible et audit‑able. 


À votre disposition pour approfondir ?

  • Un template complet d’Ansible Playbook pour le provisioning automatisé.
  • Un pipeline GitLab CI prêt‑à‑copier avec les stages test → build → registry → deploy.
  • Un générateur de run‑books (Markdown) pour chaque opération de production.

Bonne modernisation ! 🚀

Publications similaires