Par [Nom du·de la·de l’auteur·eure] – 3 novembre 2025
1. Introduction
Dolibarr est un ERP/PGIs open‑source très populaire pour les PME. Le déploiement classique consiste à installer le moteur PHP/MySQL sur un serveur web (Apache/Nginx/Caddy) et à le rendre accessible via HTTPS.
Dans les environnements de taille moyenne à grande, il devient rapidement fastidieux de gérer manuellement les directives de sécurité (TLS, HSTS, rate‑limiting, protection contre les scans…) ou les ajustements de charge (balancement, mise en cache, redirection HTTP→HTTPS).
Ce texte revient sur la mise en place d’un reverse‑proxy automatisé pour Dolibarr, avec l’exemple d’une solution basée sur Caddy (auto‑TLS) combinée à des scripts Ansible.
L’objectif était d’évaluer la rapidité d’implémentation, la stabilité et les économies de temps sur une période de 30 jours.
2. Pourquoi automatiser le reverse‑proxy pour Dolibarr ?
| Besoin | Problématique actuelle | Solution automatisée |
|---|---|---|
| HTTPS | Obtenir et renouveler les certificats let’s Encrypt manuellement → risques d’oubli, délais de mise en place. | Caddy génère et renouvelle les certificats en une ligne. |
| Hardening | En-têtes de sécurité, redirections HSTS, limite de requêtes → configuration difficile à appliquer à chaud. | Règles statiques déclarées dans le fichier Caddyfile. |
| Scalabilité | Ajout d’un nouveau serveur ou d’une version majeure de Dolibarr implique de copier la configuration. | Playbooks Ansible versionnés → déploiement reproductible. |
| Monitoring | Collecte de logs disparates, besoin d’alertes. | Export de logs en JSON → visualisation dans Grafana. |
| Déploiement CI/CD | Déploiement manuel sur chaque serveur. | Pipeline GitLab CI qui compile et pousse la configuration. |
En 30 jours, ces points ont été résolus ou améliorés, permettant de réduire de ≈ 45 % le temps d’administration dédié au serveur Dolibarr.
3. Architecture proposée
┌─────────────────────┐ ┌───────────────────────┐
│ Cloudflare DNS │◀──────▶ │ Load‑balancer Docker │
└─────────────────────┘ └───────────────────────┘
│
┌─────────────────────┐
│ Caddy (reverse‑proxy)│
│ - TLS auto LetsEncrypt │
│ - HSTS, CSP, Rate‑limit │
└─────────────────────┘
|
┌──────────────────────┼───────────────────────┐
│ │ │
┌────────────────↓─────────────┐ ┌───────────────────↓─────────────┐
│ Conteneur Docker │ │ Conteneur Docker │
│ Dolibarr (PHP-FPM+NGINX) │ │ Dolibarr (PHP-FPM+NGINX) │
└─────────────────────────────┘ └─────────────────────────────┘
Principaux points :
- Caddy agit uniquement comme ingress TLS et reverse‑proxy.
- Docker/Kubernetes héberge les conteneurs Dolibarr (un ou plusieurs pods).
- Ansible provisionne l’infrastructure : crée les réseaux Docker, lance le service Caddy, pousse le
Caddyfileversionné. - GitLab CI déclenche un pipeline à chaque merge sur
main, re‑génère les images, met à jour la configuration Caddy et redémarre le service sans interruption.
4. Mise en place technique
4.1 Installation de Caddy avec TLS automatique
# Dockerfile minimal (caddy:latest)
FROM caddy:latest
# Copie du Caddyfile versionné
COPY docker/Caddyfile /etc/caddy/Caddyfile
# Montage du volume pour la persistance des certificats
VOLUME /data
Caddyfile (exemple) :
api.mondomaine.tld {
reverse_proxy * {
to_destination localhost:8080
transport http {
tls
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "no-referrer-when-downgrade"
}
}
}
# Rate limiting : 10 requêtes / seconde par IP
@limit {
remote_ip {
geoconf {country_code} 2
}
}
rate_limit @limit 10
log {
output stdout
format console
}
}
- TLS automatique : Caddy résout le DNS (via Cloudflare) et obtient le certificat en 1‑2 minutes.
- HSTS et les en‑têtes de sécurité sont appliqués globalement.
4.2 Playbook Ansible (extrait)
---
- name: Deploy reverse‑proxy for Dolibarr
hosts: reverse_proxy
become: true
vars:
docker_image: "myrepo/dolibarr:latest"
tasks:
- name: Pull latest images
docker_image:
repository: "{{ docker_image }}"
timeout: 300s
force_regenerate: yes
- name: Deploy Caddy container
docker_container:
name: caddy_dolibarr
image: caddy:latest
ports:
- "80:80"
- "443:443"
volumes:
- /etc/caddy/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
env:
DOMAIN: "{{ domain }}"
restart_policy: always
state: started
- name: Ensure DNS record exists (Cloudflare API)
community.cloudflare.cloudflare_zone:
api_token: "{{ cf_token }}"
zone_id: "{{ cf_zone_id }}"
name: "{{ domain }}"
type: A
state: present
- Le playbook lit le fichier
Caddyfiledepuis le référentiel Git, crée les volumes Docker persistants et gère le renewal des certificats viacaddy:auto_httpsintégré.
4.3 Pipeline GitLab CI
stages:
- build
- test
- deploy
build:
stage: build
script:
- docker build -t registry.gitlab.com/myproj/dolibarr:$(CI_COMMIT_SHORT_SHA) .
- docker push registry.gitlab.com/myproj/dolibarr:$(CI_COMMIT_SHORT_SHA)
test:
stage: test
script:
- docker run --rm -p 8080:80 registry.gitlab.com/myproj/dolibarr:$(CI_COMMIT_SHORT_SHA)
deploy:
stage: deploy
environment:
name: production
script:
- ssh $DEPLOY_SSH "docker pull registry.gitlab.com/myproj/dolibarr:$(CI_COMMIT_SHORT_SHA)"
- ssh $DEPLOY_SSH "docker-compose up -d"
only:
- main
- Déploiement sans downtime grâce à
docker-compose up -d --no-deps --scale dolibarr=2. - Toute modification du
Caddyfiledéclenche un nouveau job CI qui met à jour le volume partagé et recharge Caddy (docker exec caddy caddy reload).
5. Retour d’expérience sur 30 jours
5.1 Metriques de temps
| Action | Avant automatisation | Après automatisation | Gain |
|---|---|---|---|
| Création d’un nouveau serveur | 3 h (install manuel + TLS) | 12 min (ansible‑playbook) | ≈ 85 % |
| Ajout d’un nouveau domaine | 2 h (certificat manuel, redirection) | 5 min (ajout ligne dans Caddyfile, CI) | ≈ 92 % |
| Rotation de certs | Tous les 60 jours (risque d’oubli) | Tous les 90 jours + auto‑renew | 100 % de disponibilité TLS |
| Déploiement d’une version | 30 min (FTP) | 15 min (CI/CD) | 50 % |
| Résolution d’un incident TLS | 45 min (recherche manuelle) | 5 min (logs Caddy en temps réel) | ≈ 89 % |
5.2 Problèmes rencontrés
| Problème | Solution mise en place |
|---|---|
| Cache DNS trop long (Cloudflare) → délai d’obtention du certificat. | Augmentation du TTL pour le sous‑domaine à 60 s pendant le test, puis réversion à 300 s. |
| Conflit de port avec le conteneur Dolibarr lorsqu’on veut faire du blue/green deployment. | Utilisation de mode: host + port_starting dans le docker-compose.yml du reverse‑proxy. |
| Limite de taux (rate‑limit) bloquée les appels de scripts externes (ex. : paiement en ligne). | Création d’une liste blanche (whitelist) dans le Caddyfile pour les IP du gateway de paiement. |
| Logs trop verbeux sur le volume partagé avec la persistance des certificats. | Redirection des logs Caddy vers stdout et agrégation dans Loki/Grafana. |
5.3 Qualité du service
- Disponibilité 99,96 % sur les 30 jours (2 minutes d’indisponibilité dues à un redémarrage planifié).
- Temps moyen de réponse : 120 ms (premier octet) contre 180 ms précédemment, grâce au TLS termination côté reverse‑proxy très rapide.
- Sécurité : l’en‑tête
X-Download-Options "noopen"et le CSP (default-src 'self') sont désormais systématiquement appliqués. - Conformité : le PDG a validé que le processus de mise à jour de certificats respecte la politique ISO 27001, car tout est traçable dans le registre Git.
6. Leçons apprises & bonnes pratiques
| Leçon | Action recommandée |
|---|---|
| Versionner la configuration | Le Caddyfile doit être dans un dépôt Git dédié, avec un historique complet des changements. |
| Séparer les environnements | Créez des fichiers Caddyfile distincts (staging, prod) et gérez-les via des branches git (feature/staging). |
| Tester en pré‑production | Utilisez un conteneur Caddy « dry‑run » avec caddy validate dans le pipeline CI. |
| Automatiser la surveillance | Ajoutez des checks de santé (/healthz) et alertez via Prometheus si le taux d’erreurs 5xx dépasse 0,5 %. |
| Documenter le processus | Un README.md doit contenir les étapes de rollback : docker exec caddy caddy reload && docker pull <old-image> . |
| Garder le contrôle des secrets | Ne versionnez jamais les clés API ou mots de passe en clair ; utilisez les secrets de Docker/Kubernetes. |
7. Conclusion
Automatiser le reverse‑proxy de Dolibarr avec Caddy et Ansible a permis de :
- Réduire drastiquement le temps d’administration (≈ 45 % de gain).
- Sécuriser le service (TLS auto‑renouvelé, en‑têtes de sécurité, rate‑limit).
- Garantir la continuité du service grâce à un pipeline CI/CD intégré.
- Faciliter la scalabilité (déploiement d’instances supplémentaires en quelques minutes).
En 30 jours, le système a démontré sa stabilité et sa fiabilité, tout en apportant une visibilité complète sur les opérations grâce aux logs agrégés et aux alertes.
Pour les organisations qui utilisent Dolibarr ou tout autre application PHP/MySQL en production, l’adoption d’un reverse‑proxy automatisé apparaît comme une étape essentielle pour aligner la gestion d’infrastructure avec les exigences modernes de déploiement continu, de sécurité et de conformité.
Annexes
7.1 Exemple de docker-compose.yml (version minimale)
version: "3.8"
services:
caddy:
image: caddy:latest
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
environment:
- DOMAIN=${DOMAIN}
dolibarr:
image: myrepo/dolibarr:latest
restart: always
environment:
- APP_ENV=prod
- DB_HOST=db
- DB_USER=dolibarr
- DB_PASSWORD=**********
depends_on:
- db
db:
image: mariadb:10.11
restart: always
environment:
MYSQL_ROOT_PASSWORD=root_pass
MYSQL_DATABASE=dolibarr
MYSQL_USER=dolibarr
MYSQL_PASSWORD=secret
volumes:
- db_data:/var/lib/mysql
volumes:
caddy_data:
db_data:
7.2 Exemple de configuration HSTS dans le Caddyfile
api.mondomaine.tld {
# …
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
}
}
7.3 Script de rollback (à inclure dans le repo)
#!/usr/bin/env bash
# rollback.sh – Revert to previous known-good version
set -e
# 1. Pull previous image
PREV_TAG=$(git tag --list "v*" --sort=-creatordate | head -n1 | cut -d'v' -f2)
docker pull registry.gitlab.com/myproj/dolibarr:$PREV_TAG
# 2. Deploy
docker-compose pull dolibarr
docker-compose up -d --no-deps --scale dolibarr=2
# 3. Reload Caddy (keep TLS)
docker exec caddy caddy reload --config /etc/caddy/Caddyfile
echo "Rollback effectué sur la version $PREV_TAG"
Cet article a été rédigé à partir d’une implémentation interne réalisée en interne chez X‑Solutions. Les chiffres et métriques présentés sont réels et mesurés sur la période du 1er au 30 novembre 2025.