Comment déployer, sécuriser et maintenir un environnement Dolibarr containerisé tout en respectant les exigences de conformité (RGPD, ISO 27001, PCI‑DSS, etc.)
1. Introduction
Dolibarr est un ERP/CRM léger, très apprécié des PME pour sa simplicité d’utilisation. Docker, quant à lui, offre une isolation fiable, des déploiements automatisés et une gestion cohérente des dépendances. La combinaison des deux permet d’obtenir un environnement reproductible – idéal pour répondre aux exigences de traçabilité, de journalisation et de contrôle d’accès imposées par les cadres de conformité.
Cependant, le passage d’un déploiement “classique” à un déploiement Dockerisé introduit de nouvelles contraintes : gestion des volumes persistants, secrets, configuration dynamique, et surtout conformité aux exigences légales et normatives.
Cet article passe en revue les erreurs les plus courantes, les raisons de non‑conformité et les solutions concrètes pour les corriger.
2. Architecture de référence : Dolibarr + Docker
| Élément | Image Docker officielle / Community | Rôle | Exemple de configuration |
|---|---|---|---|
| Application | dolibarr/dolibarr |
Serveur PHP‑FPM + Apache (ou Nginx) | docker run -d -p 80:80 --name dolibarr -e ... |
| Base de données | mariadb:10.11 ou postgres:15 |
Stockage persistant des données (clients, factures) | docker volume create --name dolibarr_mariadb |
| Reverse Proxy | traefik ou nginx |
Terminaison TLS, routing, HTTP/2 | docker run -d -p 443:443 ... |
| Gestion des secrets | Docker secrets ou Vault / SOPS | Stockage chiffré de clés, mots de passe DB | docker secret create db_passwd - |
| CI/CD / Orchestration | docker-compose.yml ou Kubernetes |
Déploiement, rollback, monitoring | docker-compose up -d |
| Scanning & Patch | Trivy, Clair, Anchore Engine | Analyse des vulnérabilités et mise à jour des images | trivy image dolibarr:latest |
Remarque : le choix entre MariaDB et PostgreSQL dépend de la version de Dolibarr (certaines fonctions avancées nécessitent PostgreSQL). La solution de persistance via volumes Docker ou named volumes doit être explicitement declared dans le
docker-compose.ymlpour garantir la continuité des données lors de la mise à jour ou du redéploiement.
3. Erreurs fréquentes et impact sur la conformité
| # | Erreur | Conséquence conformité | Exemple concret |
|---|---|---|---|
| 1 | Utilisation d’une version d’image non‑taguée (latest) | Difficulté à garantir la stabilité des dépendances → non‑traçabilité des patches (non‑conformité ISO 27001 A.12.6) | image: dolibarr/dolibarr sans version → latest change sans avertissement |
| 2 | Stockage des secrets en clair dans le docker-compose.yml |
Violation du principe de moindre privilège et exposition des mots de passe → non‑conformité GDPR & PCI‑DSS | db_pass: password123 dans le fichier YAML |
| 3 | Permissions de fichiers / répertoires (volume Monté en UID 0) | Risque d’escalade de privilèges, accès non‑autorisé aux logs & pièces jointes → ISO 27001 A.9.2 | user: root dans le conteneur alors que le volume /var/www/html/files est monté en chown 1000 |
| 4 | Expose de ports internes (80/443) directement au réseau hôte | Surface d’attaque accrue, auditabilité réduite → non‑conformité SOC 2 | ports: - "80:80" sans réseau Docker‑isolé |
| 5 | Absence de journalisation centralisée | Impossibilité de prouver la traçabilité des actions (exfiltration, modifications) → non‑conformité RGPD Art. 30 | Aucun fichier docker logs ou syslog persisté |
| 6 | Mise à jour manuelle sans revue de vulnérabilités | Patchs de sécurité ignorés → risque de CVE connus (ex. CVE‑2023‑XXXX) → non‑conformité ISO 27001 A.12.6 | docker pull dolibarr/dolibarr:latest sans scan |
| 7 | Pas de contrôle d’accès réseau (firewall, segmentation) | Accès direct depuis n’importe quelle partie du réseau → non‑conformité PCI‑DSS Req 2.2 | Le conteneur écoute sur 0.0.0.0 sans règle de firewall |
| 8 | Mauvaise configuration du timeout & health‑check | Conteneur bloqué en état « crashed » sans redémarrage contrôlé → perte de disponibilité & impossibilité de prouver la continuité du service | healthcheck: manquant ou interval trop long |
| 9 | Utilisation de bases de données non‑chiffrées | Données sensibles (numéros de clients, factures) exposées en transit → non‑conformité GDPR Art. 5 et PCI‑DSS Req 3.4 | |
| 10 | Absence de politique de rétention des sauvegardes | Sauvegardes trop longues → non‑respect du délai de sauvegarde prévu par la politique d’entreprise (ex. 30 jours) → non‑conformité ISO 27001 A.12.3.1 |
4. Solutions orientées conformité
4.1. Pin‑ning des images et automatisation des scans
« `yaml# docker-compose.yml (extrait)
services:
dolibarr:
image: dolibarr/dolibarr:13.0.2 # version fixe
pull_policy: if_not_present
environment:
- DB_HOST=mariadb
- DB_PASSWORD_FILE=/run/secrets/db_passwd secrets:
- db_passwd
volumes: - dolibarr_files:/var/www/html/files
- dolibarr_conf:/var/www/html/conf
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/version.php"]
interval: 30s timeout: 5s
retries: 3
start_period: 40s
- Pinning (
:13.0.2) garantit que le même binaire est déployé pendant toute la durée du cycle de vie. - Health‑check intégré permet à l’orchestrateur de détecter rapidement les dérives et de déclencher une alerte (conformité ISO 27001 A.12.4).
- Scanning automatisé (CI pipe) :
trivy image dolibarr:13.0.2avecfail_on: CVSS > 7.
4.2. Gestion sécurisée des secrets
| Outil | Pourquoi c’est conforme | Implémentation simple |
|---|---|---|
| Docker Secrets (en mode Swarm) | Stockage chiffré dans le Raft, uniquement accessible aux services qui le demandent | docker secret create db_passwd - < ./secrets/db_passwd |
| HashiCorp Vault (ou SOPS + GitOps) | Possibilité de rotation dynamique des mots de passe, audit des accès | Utiliser vault kv get -field=db_passwd secret/dolibarr et injecter via env_file |
| Kubernetes Secrets (si orchestration K8s) | Volume-mounted en mode ReadOnly, integration IAM |
kubectl create secret generic db-passwd --from-file=./db_passwd |
Bonne pratique : ne jamais placer le mot de passe en clair dans le
docker-compose.ymlou les variables d’environnement du fichier.env.
4.3. Isolation réseau & contrôle d’accès
# docker-compose.yml (extrait)
networks:
internal:
driver: bridge
public:
driver: bridge
services:
dolibarr:
networks:
- internal # le conteneur ne parle qu’aux services internes expose:
- "80"
ports:
- "8080:80" # seulement si vous devez exposer via un reverse‑proxy extérieur
exposeau lieu deportslorsqu’on ne veut pas publier directement le port.- Firewall (iptables / security‑group) : autoriser uniquement les IP des reverse‑proxies et des serveurs de monitoring.
4.4. Gestion des permissions de volumes
# Dockerfile d’override (si besoin de personnalisations)
FROM dolibarr/dolibarr:13.0.2
# Crée un user non‑root dédié
ARG DOLIBARR_UID=1000
RUN addgroup --gid $DOLIBARR_GID dolibarr && \
adduser --uid $DOLIBARR_UID --gid $DOLIBARR_GID --disabled-password --gecos "" dolibarr
# Change la propriété des répertoires sensibles
RUN chown -R dolibarr:dolibarr /var/www/html/files && \
chown -R dolibarr:dolibarr /var/www/html/conf
USER dolibarr
- Principle of Least Privilege : le conteneur tourne sous un UID/GID dédié.
chowngarantit que les répertoires montés (files,custom) ne sont pas accessibles en écriture parroot.
4.5. Journaux et audit | Élément | Solution | Conformité |
|——–|———-|———–|
| Logs applicatifs | docker logs --tail 1000 dolibarr → Forward vers un syslog central (Fluent Bit, Loki) | Preuve d’audit (ISO 27001 A.12.4) |
| Access logs du serveur web | Configurer Apache/Nginx pour écrire dans /var/logs/nginx/access.log monté en volume persistant | Référence aux événements de sécurité (PCI‑DSS Req 10.2) |
| Audit des modifications de config | Utiliser GitOps (ex. ArgoCD) : chaque changement de docker-compose.yml est versionné et approuvé | Traçabilité des changements (ISO 27001 A.9.2) |
Astuce : ajoutez
log_driver: "json-file"avecmax-size: "10m"etmax-file: "3"pour éviter la saturation du disque et garantir un volume de logs limité et contrôlé.
4.6. Sauvegardes structurées et rétention
# docker-compose.yml (extrait)
services:
backup:
image: alpine:latest
volumes:
- dolibarr_files:/data/files:ro
- dolibarr_mariadb:/data/db:ro
entrypoint: ["sh", "-c", "tar czf /backups/dolibarr_$(date +%F).tgz -C /data . && /scripts/rotate_backups.sh"]
environment:
- BACKUP_RETENTION_DAYS=30
networks:
- internal
restart: "no"
- Rotation automatisée (
rotate_backups.sh) supprime les sauvegardes de plus de30jours, conforme à la politique de rétention (ex. ISO 27001 A.12.3.1). - Les sauvegardes sont stockées dans un repo chiffré (ex.
resticourclonevers un bucket S3‑SSE) afin de respecter le chiffrement des données en repos (PCI‑DSS Req 3.4).
4.7. Patch Management et mise à jour contrôlée
| Processus | Description |
|---|---|
| CI/CD pipeline | Élaboration d’un pipeline GitLab CI : build → test → scan → push → deploy. Chaque version d’image est reviendrée avec un tag sémantique. |
| Rollback automatisé | Utiliser docker compose up -d avec la version précédente stockée dans le registre. |
| Vérification post‑déploiement | Script curl -s http://localhost/version.php | jq .version comparé à la version attendue → constat dans un ticket de change management. |
Impact Conformité : La traçabilité du Change Management (ITIL) doit être documentée ; le pipeline fournit les preuves nécessaires aux audits.
5. Checklist de conformité « Dolibarr Docker » | ✅ | Item de conformité | Comment vérifier |
|—|——————–|——————|
| 1 | Version d’image fixe | docker images → le tag doit être 13.0.2 (ou autre version controlée). |
| 2 | Secrets hors code | grep -R "db_pass" . → aucun mot de passe en clair dans les fichiers versionnés. |
| 3 | Permissions de conteneur | docker inspect dolibarr | grep User → UID non‑root (ex. 1000). |
| 4 | Health‑check actif | docker ps → le conteneur doit afficher healthy dans la colonne STATUS. |
| 5 | Journalisation centralisée | docker logs dolibarr | grep "access" → les logs apparaissent dans le SIEM. |
| 6 | Ports exposés limités | docker ps → seules les ports listées dans expose/ports sont ouvertes ; aucune ouverture non‑documentée. |
| 7 | Network isolation | docker network inspect dolibarr_network → le conteneur ne possède que les réseaux déclarés (internal). |
| 8 | Scan de vulnérabilités | trivy image dolibarr:13.0.2 → aucune CVE HIGH/CRITICAL non corrigée. |
| 9 | Sauvegarde et rétention | Script de backup exécuté quotidiennement ; rétention ≤ 30 jours vérifiable via ls -l /backups. |
|10 | Documentation de changement | Ticket JIRA contenant le commit Git et le pipeline CI‑CD qui a déployé la version. |
6. Exemple de docker-compose.yml complet (conforme) « `yaml
version: "3.8"
services:
mariadb:
image: mariadb:10.11
container_name: dolibarr_mariadb
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_pass
MYSQL_DATABASE: dolibarr
MYSQL_USER: dolibarr MYSQL_PASSWORD_FILE: /run/secrets/db_user_pass
volumes:
- dolibarr_mariadb:/var/lib/mysql
secrets: - db_root_pass
- db_user_pass
networks: -
internal
dolibarr:
image: dolibarr/dolibarr:13.0.2
container_name: dolibarr_app
restart: unless-stopped depends_on: - mariadb
environment: - DB_HOST=mariadb – DB_DATABASE=dolibarr – DB_USER=dolibarr
- DB_PASSWORD_FILE=/run/secrets/db_user_pass
- APP_URL=https://dolibarr.example.com
volumes: - dolibarr_files:/var/www/html/files – dolibarr_conf:/var/www/html/conf
secrets: - db_user_pass
networks: - internal
expose: -
"80"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/version.php"]
interval: 30s
timeout: 5s
retries: 3
start_period: 40sreverse-proxy:
image: traefik:v2.11
container_name: dolibarr_traefik
command: - "–api.insecure=true"
- "–providers.docker=true"
- "–entrypoints.web.address=:80"
- "–entrypoints.websecure.address=:443"
- "–certificatesresolvers.myresolver.acme.email=admin@example.com"
- "–certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
- "–certificatesresolvers.myresolver.acme.tlschain=true"
ports: - "80:80"
- "443:443"
- "8080:8080"
volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro"
- "letsencrypt:/letsencrypt"
networks: -
internal
restart: unless-stoppedbackup:
image: alpine:latest
container_name: dolibarr_backup
volumes: - dolibarr_files:/files:ro
- dolibarrmariadb:/db:ro
entrypoint: ["/bin/sh", "-c", "while true; do date=$(date +%F); tar czf /backups/dolibarr$date.tgz -C /files . && /scripts/rotate.sh; sleep 86400; done"]
environment: - BACKUP_RETENTION_DAYS=30
networks: - internal
restart: "no"
volumes:
dolibarr_files:
dolibarr_conf:
dolibarr_mariadb:
networks:
internal:
driver: bridge
secrets:
db_root_pass:
file: ./secrets/db_root_pass.txt
db_user_pass:
file: ./secrets/db_user_pass.txt
- **Points clés de conformité** :
*Version fixe* (`13.0.2`), *secrets injectés*, *volumes persistants* déclarés, *health‑check*, *network internal only*, *rotation des sauvegardes* avec rétention configurable, *audit des logs* via `docker logs` + SIEM.
---
## 7. Bonnes pratiques complémentaires (pour les audits)
| Domaine | Action recommandée |
|--------|--------------------|
| **Gestion des identités** | Utiliser un *service account* dédié pour chaque micro‑service, avec des permissions `read‑only` sur les volumes sensibles. |
| **Chiffrement en transit** | Terminer TLS à l’extérieur avec le reverse‑proxy; activer `ssl_protocols TLSv1.2 TLSv1.3;` dans la configuration Apache/Nginx. |
| **Chiffrement au repos** | Activer le chiffrement du volume Docker (`docker volume create --encrypt`) ou, mieux, stocker les sauvegardes dans un bucket S3‑SSE. |
| **Monitoring & alerting** | Exporter les métriques (`prometheus-docker-exporter`) et créer des alertes sur `container_restarts_total`, `cpu_usage`, `disk_usage`. |
| **Formation du personnel** | Documenter le processus de déploiement, les exigences de conformité et réaliser des réunions de sensibilisation (RGPD, ISO 27001). |
| **Tests d’intrusion** | Exécuter régulièrement des scans de vulnérabilité interne (`OpenVAS`, `Nessus`) contre le stack Dolibarr‑Docker pour vérifier l’absence de portes‑d’entrée. |
| **Documentation** | Versionner le `docker-compose.yml`, les scripts de backup, les politiques de rétention et les procédures de rollback dans un dépôt Git avec contrôle d’accès basé sur les rôles (RBAC). |
---
## 8. Conclusion
Déployer **Dolibarr dans Docker** n’est pas seulement une affaire technique : c’est une opportunité de **formaliser** les pratiques de conformité au sein de votre organisation. En évitant les erreurs classiques (versions floues, secrets en clair, permissions excessives, absence de journalisation) et en implémentant les **solutions présentées** – pin‑ning d’images, gestion sécurisée des secrets, isolation réseau, audit des logs et rotation maîtrisée des sauvegardes – vous créez un environnement **certifiable** (ISO 27001, RGPD, PCI‑DSS) tout en profitant de la flexibilité de Docker.
En suivant la checklist et la configuration d’exemple fournie, vous disposerez d’un **cadrage de conformité complet**, facilement évolutif et auditable, prêt à être intégré dans vos processus DevOps/GitOps et à satisfaire les exigences des audits internes ou externes.
---
*À retenir :* **Conformité = Processus Documenté + Contrôles Techniques + Vérification Continue**. Docker vous fournit les briques ; la vigilance et la gouvernance les assurent.
---
--- *Vous avez besoin d’un script d’automatisation pour le scan Trivy ou d’un exemple de politique de rétention ?* N’hésitez pas à me le demander, je pourrai vous fournir les templates adaptés.
---
*Bonne sécurisation !*
---
*(Cette article a été rédigé en français, orienté conformité et destiné aux équipes IT, DSI et auditors qui souhaitent industrialiser le déploiement de Dolibarr via Docker tout en respectant les exigences légales et normatives.)*