Dolibarr : comment réussir Docker orienté conformité

Guide complet (en français) pour containeriser le ERP/CRM Dolibarr tout en respectant les exigences de conformité (RGPD, PCI‑DSS, ISO 27001, etc.).


1️⃣ Pourquoi Docker & la conformité ?

Avantage Docker Impact sur la conformité
Reproductibilité – même image sur dev, test, prod. Traçabilité des versions, exigences de gestion des changements.
Isolement – chaque service tourne dans un conteneur. Principe du moindre privilège, réduction de la surface d’attaque.
Versionning & rollback (images taggées). Facilite les audit trails et les tests d’intrusion.
CI/CD intégré (GitLab CI, GitHub Actions, etc.). Continuous security testing (scans de vulnérabilités, SAST/DAST).
Logging centralisé (journaux stdout). Traçabilité des accès, indispensable aux exigences RGPD/PCI‑DSS.


2️⃣ Architecture recommandée

┌─ docker-compose.yml (ou Helm chart/terraform)                     │
│ ├─ mariadb (DB – volume chiffré) │
│ ├─ dolibarr (PHP‑FPM + Apache) │
│ ├─ redis (caching) │
│ └─ traefik (router + TLS) │
└─ Network overlay (frontend, db-backend, logs) │

  • Frontend : Reverse‑proxy Traefik (ou Nginx) avec TLS automatique (Let’s Encrypt) → https://dolibarr.mondomaine.com.
  • Application : Conteneur dolibarr:php8.2-fpm-apache (image custom, voir §4).
  • Base de données : MariaDB 10.11, data stockée sur un volume chiffré (LUKS) ou via le chiffrement au niveau du moteur.
  • Cache : Redis (optionnel, désactivable en mode production stricte).
  • Observabilité : Fluent Bit → Loki/Elasticsearch, Prometheus + Grafana, Falco pour le runtime.


3️⃣ Dockerfile « compliant » pour Dolibarr

3.1. Principes de base

  1. Image de base minimale : php:8.2-apache-bullseye-slim (ou alpine si vous avez besoin de plus de maîtrise du système de fichiers).
  2. User non‑root : créer et utiliser un utilisateur dédié (dolibarr).
  3. Chiffrement des données : montages de volumes avec driver_opts (ex : --mount type=volume,source=dolibarr_data,volume-driver=local,volume-driver-opts size=20g,volume-driver-opts=opt=uid,gid=1001,opt=mode=0600).
  4. SCAP & CVE scanning : intégrer cli-ps ou docker scan dans le pipeline CI.
  5. Hardening : désactiver les modules Apache inutiles, configurer expose_ports uniquement 80/443, définir read‑only là où c’est possible.

3.2. Exemple de Dockerfile (multi‑stage)

# 1️⃣ Build stage – récupération du code et des dépendances
FROM php:8.2-apache-bullseye-slim AS builder
# Variables d’environnement de version
ARG DOLIBRAR_VERSION=23.0.2
ENV DOLIBRAR_TAR=Dolibarr-${DOLIBRAR_VERSION}.tar.gz \
DOLIBRAR_URL=https://github.com/Dolibarr/dolibarr/archive/refs/tags/${DOLIBRAR_VERSION}.tar.gz
# Install system minimal tools
RUN apt-get update && apt-get install -y --no-install-recommends \
curl ca-certificates unzip git \
&& rm -rf /var/lib/apt/lists/*
# Téléchargement & extraction
WORKDIR /opt
RUN curl -fSL "${DOLIBRAR_URL}" -o "${DOLIBRAR_TAR}" \
&& tar -xzf "${DOLIBRAR_TAR}" \
&& mv "dolibarr-${DOLIBRAR_VERSION}" dolibarr \
&& mv dolibarr/* /var/www/html/ \
&& chown -R www-data:www-data /var/www/html \
&& chmod -R 0755 /var/www/html
# Nettoyage
RUN rm -rf /opt/dolibarr* && apt-get purge -y --auto-remove curl unzip git
# 2️⃣ Runtime stage – image finale
FROM php:8.2-apache-bullseye-slim
# Variables
ENV APACHE_DOCUMENT_ROOT="/var/www/html/public" \
DOLIBRAR_DATA="/var/lib/dolibarr_data"
# Création d'un user dédié (UID/GID = 1001)
RUN groupadd -g 1001 dolibarr && \
useradd -u 1001 -g dolibarr -m -s /sbin/nologin dolibarr && \
mkdir -p "${DOLIBRAR_DATA}" && \
chown dolibarr:dolibarr "${DOLIBRAR_DATA}" && \
chmod 0700 "${DOLIBRAR_DATA}"
# Copie de l'application (en lecture‑seule si possible)
COPY --from=builder /var/www/html /var/www/html
# Activation du module rewrite + config Apache minimale
RUN a2enmod rewrite expires && \
sed -i 's|/var/www/html|/var/www/html/public|' /etc/apache2/sites-enabled/000-default.conf
# Passer en utilisateur non‑root
USER dolibarr
# Expose uniquement les ports HTTP/HTTPS (le TLS est géré par le reverse‑proxy)
EXPOSE 80 443
# Commande par défaut (l’image Dockerfile n’est pas “interactive”, Traefik lance les conteneurs)
CMD ["apache2-foreground"]

Points de conformité intégrés

Élément Conformité
User non‑root Principe du moindre privilège (PCI‑DSS 6.2, ISO 27001 A.9).
Version fixe dans ARG DOLIBRAR_VERSION Traçabilité des versions (audit).
Mise à jour du base OS (-slim) Surface d’attaque réduite.
Chiffrement du répertoire data dans le compose (voir §6) RGPD 32‑1 (sécurité des données à caractère personnel).
Limiter les modules Apache Réduction de la surface d’attaque (CIS Benchmarks).


4️⃣ docker‑compose.yml orienté conformité

version: "3.9"
services:
# -------------------------------------------------------
# 1️⃣ Traefik (router TLS)
# -------------------------------------------------------
traefik:
image: traefik:v2.11
command:
- "--api.insecure=false"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.email=admin@mondomaine.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.myresolver.acme.httpchallallenge.entrypoint=web"
ports:
- "80:80"
- "443:443"
- "8080:8080" # Dashboard (désactiver en prod ou y restreindre)
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "letsencrypt:/letsencrypt"
networks:
- proxy
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# -------------------------------------------------------
# 2️⃣ MariaDB (DB chiffrée)
# -------------------------------------------------------
mariadb:
image: mariadb:10.11
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: dolibarr
MYSQL_USER: dolibarr
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- dolibarr_mariadb:/var/lib/mysql
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro # scripts de création
# Chiffrement au niveau du volume (exemple avec local driver, chiffrement AES‑256)
deploy:
resources:
limits:
memory: "1G"
security_opt:
- no-new-privileges:true
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# -------------------------------------------------------
# 3️⃣ Dolibarr (PHP‑FPM + Apache)
# -------------------------------------------------------
dolibarr:
build:
context: ./docker/dolibarr
dockerfile: Dockerfile
restart: unless-stopped
environment:
# Variables de connexion à la BD
DB_SERVER: mariadb
DB_NAME: dolibarr
DB_USER: dolibarr
DB_PASSWORD: ${MYSQL_PASSWORD}
# Optionnel : activation du cache Redis
REDIS_HOST: redis
volumes:
- dolibarr_data:/var/lib/dolibarr_data # Persisté, volume chiffré → voir §6
- ./docker/dolibarr/php.ini:/usr/local/etc/php/conf.d/custom.ini:ro # config PHP sécurisée
networks:
- db
- proxy
depends_on:
- mariadb
- redis
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
security_opt:
- no-new-privileges:true
- read_only:true # tout le reste en RO sauf /tmp
- seccomp:./seccomp/dolibarr.json
# -------------------------------------------------------
# 4️⃣ Redis (caching)
# -------------------------------------------------------
redis:
image: redis:7-alpine
restart: unless-stopped
command: ["redis-server", "--save", "", "--appendonly", "no"]
volumes:
- redis_data:/data
security_opt:
- no-new-privileges:true
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "2"
networks:
db:
driver: bridge
proxy:
driver: bridge
volumes:
dolibarr_mariadb:
dolibarr_data:
redis_data:
letsencrypt:

4.1. Points de conformité dans le compose

Élément Pourquoi c’est conforme
restart: unless-stopped Garantit la résilience sans dépendances humaines.
security_opt: no-new-privileges:true Empêche l’escalade de privilèges à l’intérieur du conteneur.
read_only:true (sauf /tmp) Limite la persistance uniquement aux volumes explicitement montés → intégrité des fichiers (PCI‑DSS 6.5).
seccomp custom Bloque les appels système non‑autorisés (ex : mount, ptrace).
Volume séparé dolibarr_data Peut être provisionné avec chiffrement au niveau du driver (ex : local-pvc avec options=encrypt_key).
Limites de logs (max-size) Évite la saturation du disque, nécessaire aux politiques de rétention (ISO 27001 A.12.4).
Variables d’environnement (sensibles) Centralisées, injectées via un secret manager (Docker Secrets ou Kubernetes Secrets) plutôt que hard‑coded.


5️⃣ Gestion de la conformité (processus & artefacts)

5.1. Gouvernance des images

  1. Tagging : dolibarr:23.0.2-prod-2025-11-03 (version + date de release).
  2. Signature : utilisation de Notary / Cosign pour signer chaque image.
  3. Scanners : intégrer trivy, clair ou anchore dans le pipeline CI pour détecter CVEs et violations de baselines.

# Exemple de job GitLab CI
image-scan:
image: aquasec/trivy:latest
stage: test
script:
- trivy image --severity HIGH,CRITICAL --exit-code 1 docker.io/myorg/dolibarr:${IMAGE_TAG}
rules:
- if: $CI_COMMIT_BRANCH == "main"

5.2. Politique de changement

  • Change Control Board (CCB) virtuel (Git Merge Request) : chaque mise à jour de l’image doit être revue par le Security Officer.
  • Rollback : garder au moins 3 images dans le registre (latest, prev, prev2) pour un retour rapide.

5.3. Gestion des secrets

  • Utiliser Docker Secrets ou HashiCorp Vault pour injecter MYSQL_ROOT_PASSWORD, MYSQL_PASSWORD.
  • Ne jamais placer les secrets dans le dépôt Git.

5.4. Audits et preuves

Auditre Artefact à fournir
ISO 27001 Liste des contrôles de sécurité, diagramme d’architecture, politique de sauvegarde, processus de changement.
PCI‑DSS Preuve du chiffrement des données au repos (volumes dolibarr_data), journalisation des accès (Fluent Bit), modification du code source (repo immutable).
RGPD Registre des traitements, preuves de privacy by design (ex : désactivation de la journalisation des champs PII, chiffrement TLS end‑to‑end).
SOC‑2 Rapports de conformité des conteneurs (CIS Benchmarks), logs d’accès (audit).

5.5. Sauvegarde & DR

# Exemple de backup quotidien (cron job hors conteneur)
# docker exec mariadb mysqldump -u dolibarr -p${MYSQL_PASSWORD} dolibarr \
# | gzip > /backup/${DATE}.sql.gz
# Puis upload vers un bucket S3 chiffré (KMS‑managed)

  • RPO ≤ 15 min, RTO ≤ 30 min.
  • Vérifier régulièrement la restauration (tableaux de restaurations).


6️⃣ Sécurisation du réseau et du périmètre

Action Implémentation
Segmentation Placer le container Dolibarr dans un réseau dédié (proxy) et le réseau db uniquement accessible par le conteneur mariadb.
Whitelist IPs Dans Traefik, autoriser uniquement les IPs de votre corporate ou vos points d’entrée VPN.
TLS Forcer HTTPS Only via entryPoints.websecure.
Firewall Appliquer un firewall host (e.g., ufw ou le security group cloud) qui ne laisse que 80/443 sortants et 22/TCP entrant (pour bastion).
ACS Mettre en place des Healthchecks (healthcheck: test: ["CMD","curl","-f","http://localhost/health"]) et lier à la plateforme d’orchestration (Docker Swarm/K8s).


7️⃣ Observabilité & Alerting

Métrique Source Pourquoi
Latence HTTP Traefik metrics + Prometheus Détection de dégradations de service.
Erreurs 5xx Access logs (Fluent Bit) Indicateurs d’incidents applicatifs.
Intégrité des fichiers Falco (détection de modification de /var/www/html non autorisée) Garantit l’immutabilité du code.
Conformité des logs Logrotate + conservé dans Elasticsearch (retention ≥ 90 jours) Preuve d’audit pour les exigences RGPD.
CVE scanning CI pipeline (Trivy) Preuve d’un processus de gestion des vulnérabilités.

Exemple de règle Falco (défaut : écrire hors /tmp) :

- rule: Write to unexpected path in Dolibarr container
evt.type = syscall
syscall = write
container.id = <dolibarr_container_id>
write.path startswith /var/www/html and not event.type in (chmod, chown)
Priority = WARNING
Description = "Tentative d'écriture dans le code source"


8️⃣ Bonnes pratiques supplémentaires

# Pratique Justification
1 Versionnage de la configuration (gitops) Toute modification d’infrastructure passe par Pull Request, audit & CI.
2 Déployer en canary (ex : 5 % du trafic) avant rollout complet Réduit le risque d’impact en production.
3 Pen‑test automatisé (owasp zap) dans le pipeline Vérifie continuellement la conformité PCI‑DSS.
4 Documentation d’architecture (README + diagram Addr) disponible en Wiki interne. Facilite le knowledge transfer et les audits.
5 Réduction du TTL des images (image: myorg/dolibarr:23.0.2 au lieu de latest) Garantit un pin exact de l’image, évite les surprises.
6 Déploiement immutable : on ne modifie jamais un conteneur existant, on crée un nouveau with un nouveau tag. Facilite le rollback et évite les dérives d’état.
7 Gestion des sessions : config php_value(session.cookie_httponly=1) et session.cookie_secure=1. Renforce la protection des cookies contre le vol.
8 Expiration des tokens : dolibarr_session_lifetime ≤ 8 h. Limite la fenêtre d’exploitation en cas de compromission.


9️⃣ Conclusion – Checklist de mise en production

Action
1 Build de l’image Docker (Dockerfile) avec tags immuables.
2 Scan de vulnérabilités (trivy, claire).
3 Signature de l’image (cosign sign).
4 Push vers registre privé (registry chiffré).
5 Déploiement via docker stack deploy (Swarm) ou helm upgrade.
6 Validate TLS (certificat Let’s Encrypt valide).
7 Test de connexion à la BD (ex: curl http://mariadb:3306).
8 Vérifier les logs (pas de fuite de mots de passe).
9 Monitoring : alertes configurées sur 5xx, latence > 500 ms, CPU > 80 %.
10 Backup quotidien + test de restauration mensuel.
11 Document la procédure de rollback et assigner la responsabilité.
12 Informer le DPO / Responsable Sécurité du déploiement.


🎯 Vous avez maintenant :

  • Un Dockerfile hardené pour Dolibarr.
  • Un docker‑compose qui intègre le chiffrement des volumes, le principe du moindre privilège, le logging maîtrisé, les limites de ressources, et le réseau segmenté.
  • Un processus de conformité (traçabilité, signatures, scans, sauvegarde, audit).
  • Des outils d’observabilité et d’alerting compatibles avec les exigences RGPD/PCI‑DSS.

En suivant ces étapes, votre instance Dolibarr fonctionnera dans un environnement conteneurisé, audit‑ready, résilient et alignée avec les standards de conformité les plus stricts.

Bon déploiement ! 🛡️🚀

Publications similaires