Aller au contenu principal
Privacy Self-Hosting Security

Comment auto-héberger Plausible Analytics : un guide axé sur la confidentialité pour VPS

Guide étape par étape pour auto-héberger Plausible Analytics sur Hetzner avec Podman, Caddy et un durcissement avancé de la sécurité. Conforme au RGPD, sans Docker, contrôle total.

8 min
self host plausible analytics fr

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 sudo pour 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_BASE signe 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

  1. Allez dans Hetzner Cloud ConsoleNetworkingEnable IPv6.

  2. 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.

  1. Définissez TOTP_VAULT_KEY dans .env (déjà fait dans le fichier d’environnement ci-dessus).

  2. Connectez-vous à votre dashboard Plausible sur https://analytics.votredomaine.com.

  3. Allez dans SettingsSecurityEnable 2FA.

  4. 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é)

  1. Installez Tailscale :

    curl -fsSL https://tailscale.com/install.sh | sh
    sudo tailscale up
  2. 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

  1. Configurez WireGuard sur votre serveur.

  2. 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èmeCauseSolution
ClickHouse OOMRAM insuffisanteDéfinissez Memory=1g dans le fichier Quadlet
Géolocalisation en échecX-Forwarded-For manquantVérifiez que Caddy configure les en-têtes correctement
Certificat Caddy en échecDNS non propagéExécutez dig +short analytics.votredomaine.com
Plausible ne démarre pasSECRET_KEY_BASE modifiéRestaurez la clé originale
IPv6 ne fonctionne pasIPv6 non activé sur HetznerActivez dans la Cloud Console
Le conteneur s’arrête après déconnexionLingering non activéExécutez sudo loginctl enable-linger $USER
Permission refusée sur les volumesContexte SELinux incorrectAjoutez 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 sudo pour les conteneurs

  • NoNewPrivileges=true sur tous les conteneurs

  • DropCapability=ALL + AddCapability minimal

  • Limites mémoire et PID sur tous les conteneurs

  • Plausible écoute sur 127.0.0.1 uniquement (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

  1. Testez votre installation : Visitez https://analytics.votredomaine.com et vérifiez que le dashboard se charge.

  2. Surveillez les logs : Utilisez journalctl --user -u plausible -f pour déboguer.

  3. Sauvegardez régulièrement : Utilisez pg_dump pour PostgreSQL et clickhouse-client pour ClickHouse.

Besoin d’aide ? Contactez Renard Digital — nous aidons les entreprises à s’auto-héberger en toute confiance.

Tags

#Plausible Analytics #Podman #Hetzner #Caddy #GDPR #2FA #Dual-Stack

Un projet web ?

Renard Digital vous accompagne de A à Z : site, domaine, email.

Contactez-nous