Comment auto-héberger Plausible Analytics : un guide axé sur la confidentialité pour VPS
Comment auto-héberger Plausible Analytics : un guide axé sur la confidentialité pour VPS
Reprenez le contrôle de vos analytics — sans sacrifier la confidentialité ni la sécurité.
Google Analytics suit vos visiteurs. Il vous suit aussi. Chaque clic, chaque scroll, chaque session est enregistré, analysé et monétisé. Pour les petites entreprises, les freelances et les équipes soucieuses de la vie privée, c’est rédhibitoire.
Plausible Analytics offre une alternative légère et open source. Elle est conforme au RGPD par défaut, n’utilise pas de cookies et ne collecte aucune donnée personnelle. Mais pourquoi s’arrêter là ? L’auto-hébergement de Plausible vous donne un contrôle total sur vos données, votre sécurité et votre vie privée.
Dans ce guide, nous verrons comment auto-héberger Plausible Analytics sur un VPS Hetzner en utilisant Podman (pas Docker), Caddy pour le HTTPS automatique, et un durcissement avancé de la sécurité — incluant 2FA, double-stack (IPv4 + IPv6) et accès au dashboard via VPN uniquement.
Pourquoi auto-héberger Plausible ?
Confidentialité d’abord
-
Pas de cookies : Contrairement à Google Analytics, Plausible ne suit pas les utilisateurs entre les sites.
-
Pas de données personnelles : Seules des métriques agrégées (pages vues, référents, appareils).
-
Conforme au RGPD : Pas besoin de bannières de cookies ni de pop-ups de consentement.
La sécurité par conception
-
Contrôle total : Vos données restent sur votre serveur — aucun accès tiers.
-
Podman rootless : Exécutez les conteneurs sans
sudopour une meilleure isolation. -
Durcissement avancé : Pare-feu, fail2ban, SELinux et plus encore.
Économique
-
Gratuit : Pas de frais mensuels (vs les plans hébergés de Plausible à 9 $+/mois).
-
Évolutif : Commencez avec un VPS Hetzner à 4,50 €/mois et évoluez selon vos besoins.
Prérequis
Avant de commencer, assurez-vous d’avoir :
✅ Un VPS Hetzner (CX21 : 2 vCPU, 4 Go RAM, 40 Go SSD recommandé).
✅ Un nom de domaine (ex. : analytics.votredomaine.com).
✅ Des bases en Linux (SSH, commandes terminal).
✅ Podman 5.0+ (rootless, sans daemon).
Étape 1 : Durcissement du serveur (sécurité avancée)
Règles de pare-feu
Restreignez l’accès aux seuls ports essentiels (SSH, HTTP, HTTPS) :
sudo apt update && sudo apt install -y ufw
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP (pour Let's Encrypt)
sudo ufw allow 443/tcp # HTTPS
sudo ufw deny all # Bloquer tout le reste
sudo ufw enable
Créer un utilisateur dédié
N’exécutez jamais de services en tant que root. Créez un utilisateur dédié pour Plausible :
sudo useradd -r -s /bin/false plausible
Sécuriser SSH
Désactivez la connexion root et imposez les clés SSH :
sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sudo systemctl restart sshd
Installer Fail2ban
Bloquez les attaques par force brute :
sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
Étape 2 : Installer Podman
Podman est une alternative sans daemon et rootless à Docker. Il est plus sécurisé et s’intègre parfaitement avec systemd.
sudo apt update && sudo apt install -y podman podman-docker
Configurer Podman rootless
Autorisez votre utilisateur à exécuter des conteneurs sans sudo :
sudo usermod --add-subuids 100000-165535 $USER
sudo usermod --add-subgids 100000-165535 $USER
Activer le linger
Assurez-vous que les conteneurs persistent après la déconnexion :
sudo loginctl enable-linger $USER
Étape 3 : Déployer Plausible avec Quadlet
Quadlet est la méthode déclarative de Podman pour gérer les conteneurs avec systemd. C’est plus propre et plus maintenable qu’un docker-compose.yml.
Créer le répertoire Quadlet
mkdir -p ~/.config/containers/systemd/plausible
Conteneur PostgreSQL
Créez ~/.config/containers/systemd/plausible/plausible-postgres.container :
[Unit]
Description=Plausible PostgreSQL Database
After=network-online.target
Wants=network-online.target
[Container]
Image=docker.io/postgres:16-alpine
ContainerName=plausible-postgres
Environment=POSTGRES_DB=plausible
Environment=POSTGRES_USER=plausible
EnvironmentFile=%h/volumes/plausible/.env
Volume=%h/volumes/plausible/postgres-data:/var/lib/postgresql/data:Z
HealthCmd=pg_isready -U plausible
HealthInterval=30s
AutoUpdate=registry
Network=plausible.network
NoNewPrivileges=true
DropCapability=ALL
AddCapability=CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_SETUID,CAP_SETGID
Memory=512m
PidsLimit=200
[Service]
Restart=always
RestartSec=5
[Install]
WantedBy=default.target
Conteneur ClickHouse
Créez ~/.config/containers/systemd/plausible/plausible-clickhouse.container :
[Unit]
Description=Plausible ClickHouse Analytics Database
After=network-online.target
Wants=network-online.target
[Container]
Image=docker.io/clickhouse/clickhouse-server:24.3-alpine
ContainerName=plausible-clickhouse
Volume=%h/volumes/plausible/clickhouse-data:/var/lib/clickhouse:Z
HealthCmd=wget --spider -q http://localhost:8123/ping
HealthInterval=30s
AutoUpdate=registry
Network=plausible.network
NoNewPrivileges=true
DropCapability=ALL
AddCapability=CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_SETUID,CAP_SETGID
Ulimit=nofile=262144:262144
Memory=1g
PidsLimit=500
[Service]
Restart=always
RestartSec=5
[Install]
WantedBy=default.target
Conteneur de l’application Plausible
Créez ~/.config/containers/systemd/plausible/plausible.container :
[Unit]
Description=Plausible Analytics Web Application
After=network-online.target
After=plausible-postgres.service
After=plausible-clickhouse.service
Wants=network-online.target
[Container]
Image=ghcr.io/plausible/community-edition:v3.2.1
ContainerName=plausible
PublishPort=127.0.0.1:8000:8000
EnvironmentFile=%h/volumes/plausible/.env
HealthCmd=curl -fsS http://localhost:8000/api/health || exit 1
HealthInterval=30s
AutoUpdate=registry
Network=plausible.network
NoNewPrivileges=true
DropCapability=ALL
AddCapability=CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_SETUID,CAP_SETGID
Memory=256m
PidsLimit=100
[Service]
Restart=always
RestartSec=5
[Install]
WantedBy=default.target
Configuration réseau
Créez ~/.config/containers/systemd/plausible/plausible.network :
[Network]
Description=Plausible internal network
Internal=false
DNSEnabled=true
Fichier d’environnement
Créez ~/volumes/plausible/.env :
# Requis
BASE_URL=https://analytics.votredomaine.com
SECRET_KEY_BASE=$(openssl rand -base64 48) # Générez une fois, sauvegardez sécuritairement
TOTP_VAULT_KEY=$(openssl rand -base64 32) # Pour la 2FA
# URLs de base de données
DATABASE_URL=postgres://plausible:${POSTGRES_PASSWORD}@plausible-postgres:5432/plausible
CLICKHOUSE_DATABASE_URL=http://plausible:secret@plausible-clickhouse:8123/plausible
# Postgres
POSTGRES_PASSWORD=votre-mot-de-passe-fort-ici
# SMTP (pour les réinitialisations de mot de passe et rapports par email)
SMTP_HOST_ADDR=smtp.resend.com
SMTP_HOST_PORT=587
SMTP_USER_NAME=resend_api_key
SMTP_USER_PWD=re_xxxxxxxxxxxx
MAILER_EMAIL=[email protected]
# Sécurité
DISABLE_REGISTRATION=invite_only
# Confidentialité
CLICKHOUSE_MAX_DATA_RETENTION_DAYS=30 # Rétention de 30 jours
IP_ANONYMIZATION=true # Désactiver le suivi IP
⚠️ Important :
SECRET_KEY_BASEsigne toutes les sessions utilisateur. Si vous le modifiez après le premier démarrage, chaque session existante et chaque lien de réinitialisation de mot de passe seront invalidés. Sauvegardez-le en lieu sûr.
Démarrer les services
systemctl --user daemon-reload
systemctl --user start plausible-postgres plausible-clickhouse
systemctl --user start plausible
systemctl --user enable plausible-postgres plausible-clickhouse plausible
Vérifiez que tout fonctionne :
systemctl --user status plausible
curl -I http://localhost:8000
Étape 4 : Reverse proxy avec Caddy (HTTPS automatique)
Caddy provisionne automatiquement les certificats Let’s Encrypt et impose le HTTPS. Pas de certbot, pas de cron jobs, pas de renouvellements manuels.
Installer Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy
Configurer Caddy
Créez /etc/caddy/Caddyfile :
analytics.votredomaine.com {
encode gzip zstd
reverse_proxy 127.0.0.1:8000 {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
# En-têtes de sécurité
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
# Bloquer les bots
@bots header_regexp User-Agent "(bot|crawl|spider|slurp|semrush|ahrefs|dotbot)"
respond @bots 403
}
Démarrer Caddy
sudo systemctl enable --now caddy
Étape 5 : Double-stack (IPv4 + IPv6)
Activer IPv6 dans la console Hetzner Cloud
-
Allez dans Hetzner Cloud Console → Networking → Enable IPv6.
-
Attribuez une adresse IPv6 à votre serveur.
Configurer Caddy pour IPv6
Mettez à jour votre /etc/caddy/Caddyfile pour écouter en IPv4 et IPv6 :
analytics.votredomaine.com {
bind ::
...
}
Vérifier la connectivité IPv6
curl -6 https://analytics.votredomaine.com
Étape 6 : Activer la 2FA pour le dashboard Plausible
Plausible supporte la 2FA basée sur TOTP pour le dashboard administrateur.
-
Définissez
TOTP_VAULT_KEYdans.env(déjà fait dans le fichier d’environnement ci-dessus). -
Connectez-vous à votre dashboard Plausible sur
https://analytics.votredomaine.com. -
Allez dans Settings → Security → Enable 2FA.
-
Scannez le QR code avec Google Authenticator, Authy ou toute app TOTP.
Chaque connexion nécessite désormais un code temporel depuis votre téléphone. Même si votre mot de passe est compromis, votre dashboard reste protégé.
Étape 7 : Optimisations de confidentialité
Anonymisation des IPs
Déjà activée via IP_ANONYMIZATION=true dans .env. Plausible tronque les IPs des visiteurs avant de les stocker — rendant impossible l’identification d’utilisateurs individuels.
Rétention des données
Déjà définie à 30 jours via CLICKHOUSE_MAX_DATA_RETENTION_DAYS=30. Les données d’analytics plus anciennes sont automatiquement purgées. Pas de thésaurisation, pas de surprises.
Restreindre l’accès au dashboard via VPN
Pour une sécurité maximale, restreignez le dashboard Plausible à un VPN pour que seuls vous (et votre équipe) puissiez y accéder.
Option A : Tailscale (recommandé)
-
Installez Tailscale :
curl -fsSL https://tailscale.com/install.sh | sh sudo tailscale up -
Mettez à jour Caddy pour n’écouter que sur votre IP Tailscale :
analytics.votredomaine.com { bind 100.x.y.z # Votre IP Tailscale ... }
Option B : WireGuard
-
Configurez WireGuard sur votre serveur.
-
Mettez à jour Caddy pour écouter sur l’IP de l’interface WireGuard.
Le script de suivi (/js/script.js) continue de fonctionner pour tous les visiteurs — seul le dashboard admin est verrouillé derrière le VPN.
Étape 8 : Pièges courants et solutions
| Problème | Cause | Solution |
|---|---|---|
| ClickHouse OOM | RAM insuffisante | Définissez Memory=1g dans le fichier Quadlet |
| Géolocalisation en échec | X-Forwarded-For manquant | Vérifiez que Caddy configure les en-têtes correctement |
| Certificat Caddy en échec | DNS non propagé | Exécutez dig +short analytics.votredomaine.com |
| Plausible ne démarre pas | SECRET_KEY_BASE modifié | Restaurez la clé originale |
| IPv6 ne fonctionne pas | IPv6 non activé sur Hetzner | Activez dans la Cloud Console |
| Le conteneur s’arrête après déconnexion | Lingering non activé | Exécutez sudo loginctl enable-linger $USER |
| Permission refusée sur les volumes | Contexte SELinux incorrect | Ajoutez le suffixe :Z aux montages de volumes |
Notes finales
🔒 Récapitulatif de la checklist sécurité
-
Pare-feu : seuls les ports 22, 80, 443 ouverts
-
SSH : connexion root désactivée, clés uniquement
-
Fail2ban : blocage des attaques par force brute
-
Podman rootless : pas de
sudopour les conteneurs -
NoNewPrivileges=truesur tous les conteneurs -
DropCapability=ALL+AddCapabilityminimal -
Limites mémoire et PID sur tous les conteneurs
-
Plausible écoute sur
127.0.0.1uniquement (pas public) -
HTTPS imposé via Caddy + en-têtes de sécurité
-
2FA activée sur le dashboard
-
DISABLE_REGISTRATION=invite_only -
Rétention de 30 jours avec anonymisation IP
-
Dashboard verrouillé derrière un VPN (optionnel mais recommandé)
🚀 Essayez la bêta de Parlant.dev
Vous cherchez un moyen plus simple d’auto-héberger des outils respectueux de la vie privée ? Rejoignez la bêta de Parlant.dev — une plateforme gérée et open source qui élimine la complexité de la gestion de votre propre infrastructure.
📣 Syndication
Cet article est prêt pour Dev.to, Medium et LinkedIn. Lors de la syndication, ajoutez ce pied de page :
Initialement publié sur Renard Digital.
Prochaines étapes
-
Testez votre installation : Visitez
https://analytics.votredomaine.comet vérifiez que le dashboard se charge. -
Surveillez les logs : Utilisez
journalctl --user -u plausible -fpour déboguer. -
Sauvegardez régulièrement : Utilisez
pg_dumppour PostgreSQL etclickhouse-clientpour ClickHouse.
Besoin d’aide ? Contactez Renard Digital — nous aidons les entreprises à s’auto-héberger en toute confiance.