Mon architecture d'auto-hébergement Docker, de A à Z
L'architecture Docker que je déploie chez mes clients : Traefik, CrowdSec, Grafana, backups automatisés. Tout ce que j'ai appris en production.
Ça fait plusieurs années que je déploie la même architecture Docker chez mes clients — startups, PME, projets perso. À force d’itérations, j’ai une stack qui tient la route : sécurisée, monitorée, avec des backups qui fonctionnent (et que je teste, ce qui n’est pas la même chose).
Cet article, c’est le condensé de tout ça. Pas de théorie, que du concret — les mêmes fichiers de config que j’utilise en production.
La stack complète
Voici ce qu’on va mettre en place :
- Traefik comme reverse proxy avec HTTPS automatique via Let’s Encrypt
- CrowdSec pour la détection d’intrusions
- Grafana + Prometheus + Loki pour le monitoring et les logs
- Backups automatisés et testés
- Le tout orchestré par Docker Compose
# Vue d'ensemble de la stack
services:
traefik: # Reverse proxy + HTTPS auto
crowdsec: # Détection d'intrusions collaborative
prometheus: # Collecte de métriques
grafana: # Visualisation
loki: # Agrégation de logs
backup: # Sauvegarde automatisée
Traefik : le seul reverse proxy dont vous avez besoin
Si vous utilisez encore Nginx avec des fichiers de conf par service, Traefik va vous changer la vie. Le principe : vos containers Docker déclarent des labels, et Traefik les détecte automatiquement. Vous ajoutez un service ? Traefik le route. Pas de fichier à modifier, pas de reload.
Le HTTPS est géré via Let’s Encrypt avec un DNS challenge — l’API de votre registrar (OVH, Gandi, etc.) confirme la propriété du domaine. Tous les certificats se renouvellent tout seuls. Le HTTP est redirigé vers HTTPS par défaut.
# docker-compose.yml
name: traefik
services:
traefik:
image: traefik:v3.2
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.letsencrypt.acme.dnschallenge=true
- --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=ovh
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./acme.json:/acme.json
labels:
- traefik.enable=true
- traefik.http.routers.${APP_NAME}.rule=Host(`traefik.${DOMAIN}`)
- traefik.http.routers.${APP_NAME}.tls.certresolver=letsencrypt
Une fois en place, vous ne touchez plus jamais à Traefik. Chaque nouveau service, c’est trois labels dans votre docker-compose.yml et c’est réglé.
CrowdSec : le fail2ban qui ne vit pas dans une grotte
Si vous utilisez encore fail2ban, CrowdSec fait la même chose en mieux. Il analyse vos logs en temps réel et bloque les IPs malveillantes — jusque-là, rien de nouveau. La différence : c’est collaboratif. Les IPs détectées par d’autres utilisateurs CrowdSec sont partagées. Vous bénéficiez de la détection de milliers de serveurs, pas juste du vôtre.
crowdsec:
image: crowdsecurity/crowdsec
volumes:
- ./crowdsec/acquis.yaml:/etc/crowdsec/acquis.yaml
- /var/log:/var/log:ro
- crowdsec-db:/var/lib/crowdsec/data
environment:
- COLLECTIONS=crowdsecurity/traefik crowdsecurity/http-cve
Monitoring : savoir ce qui se passe avant vos utilisateurs
J’ai détaillé ma philosophie du monitoring dans un article dédié. Ici, le concret :
- Prometheus scrape les métriques — temps de réponse, CPU, mémoire, espace disque
- Loki agrège les logs de tous vos containers — fini le
docker logsen SSH - Grafana affiche tout dans un seul dashboard
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
grafana:
image: grafana/grafana
labels:
- traefik.enable=true
- traefik.http.routers.grafana.rule=Host(`grafana.${DOMAIN}`)
- traefik.http.routers.grafana.tls.certresolver=letsencrypt
loki:
image: grafana/loki
volumes:
- loki-data:/loki
Ajoutez des alertes Prometheus — au minimum : espace disque > 85 %, taux d’erreurs HTTP qui dérape, et un container qui redémarre en boucle. Si vous ne configurez pas d’alertes, autant ne pas avoir de monitoring.
Backups : testez-les ou priez
Tout le monde a des backups. Presque personne ne les teste. Et le jour où il faut restaurer, c’est la loterie.
#!/bin/bash
# backup.sh — exécuté quotidiennement via cron
set -euo pipefail
BACKUP_DIR="/backups/$(date +%Y-%m-%d)"
mkdir -p "$BACKUP_DIR"
# Dump PostgreSQL
docker exec postgres pg_dumpall -U postgres | gzip > "$BACKUP_DIR/postgres.sql.gz"
# Volumes Docker
for vol in $(docker volume ls -q); do
docker run --rm -v "$vol:/data" -v "$BACKUP_DIR:/backup" \
alpine tar czf "/backup/$vol.tar.gz" /data
done
# Sync distant
rclone sync "$BACKUP_DIR" remote:backups/$(date +%Y-%m-%d) --transfers 4
# Nettoyage des backups > 30 jours
find /backups -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;
echo "Backup terminé : $(du -sh $BACKUP_DIR | cut -f1)"
C’est d’ailleurs cette problématique qui m’a poussé à créer RestoreProof — un outil de vérification automatisée de backups.
Hardening : ce que 90 % des gens oublient
Quatre choses à faire sur tout serveur, sans exception :
- SSH : désactiver le mot de passe, clés uniquement. Si vous ne faites qu’une seule chose de cette liste, faites celle-là
- UFW : ouvrir 80, 443 et votre port SSH custom. Tout le reste fermé
- CrowdSec : en complément du firewall pour filtrer le trafic applicatif
- Updates auto :
unattended-upgradespour les patchs de sécurité. Pas de “je le ferai demain”
# Hardening SSH rapide
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#Port 22/Port 2222/' /etc/ssh/sshd_config
systemctl restart sshd
# UFW
ufw default deny incoming
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 2222/tcp
ufw enable
Ce que je fais tourner avec cette stack
Pour vous donner une idée, voici le genre de services que je déploie avec cette architecture chez mes clients — et pour moi-même :
- Nextcloud pour les fichiers, le calendrier, les contacts
- Gitea ou Forgejo pour le code
- Matrix Synapse + Element pour la messagerie chiffrée
- Vaultwarden pour les mots de passe
- Et tout ce qui se dockerise
Le tout avec HTTPS automatique, monitoring, logs centralisés, sécurité proactive et backups testés. Sur un serveur dédié à ~45 €/mois. Les mêmes services en SaaS, c’est 300 €+ par mois pour une équipe de 15 personnes.
Si vous voulez que je mette ça en place chez vous, c’est exactement ce que couvre le Pack Infra Sécurisée.
Besoin d'aide sur ce sujet ?
Réserver un créneau