Self-hosting di Plausible Analytics su un VPS con Docker Compose
Installa Plausible Community Edition sul tuo VPS con Docker Compose. Guida completa che copre setup, integrazione dello script di tracciamento, eventi personalizzati, backup e aggiornamenti.
Plausible Analytics offre web analytics senza cookie, senza raccolta di dati personali e senza banner di consenso. Ospitare la Community Edition sul proprio server significa che i dati dei visitatori non escono mai dalla tua macchina. Questa guida copre l'intero ciclo di vita: deployment di Plausible CE v3.2.0 con Docker Compose, integrazione dello script di tracciamento, configurazione di eventi personalizzati, backup e aggiornamenti.
Prerequisiti: Un VPS con almeno 4 GB di RAM con Docker e Docker Compose Docker in produzione su un VPS: cosa si rompe e come risolvere, un nome di dominio puntato al tuo server, e un reverse proxy che gestisce TLS Traefik vs Caddy vs Nginx: reverse proxy Docker a confronto.
Cos'è Plausible Community Edition e in cosa differisce dalla versione Cloud?
Plausible CE è la versione self-hosted, gratuita e con licenza AGPL di Plausible Analytics. Funziona come tre container Docker: l'applicazione web Plausible (Elixir), PostgreSQL per gli account utente e ClickHouse per l'archiviazione degli eventi analitici. Ottieni la stessa dashboard rispettosa della privacy della versione cloud a pagamento. I tuoi dati restano sul tuo server. La CE viene rilasciata due volte l'anno come release a supporto a lungo termine.
Le differenze:
| Funzionalità | Cloud | Community Edition |
|---|---|---|
| Dashboard analitica | Sì | Sì |
| Privacy-first (senza cookie) | Sì | Sì |
| Eventi e obiettivi personalizzati | Sì | Sì |
| Stats API (v2) | Sì | Sì |
| Report via email | Sì | Sì (richiede SMTP) |
| Funnel e obiettivi di fatturato | Sì | No |
| Sites API | Sì | No |
| Connettore Looker Studio | Sì | No |
| Integrazione Google Search Console | Sì | Sì (richiede configurazione) |
| SSO / gestione team | Sì | No |
| Supporto premium | Sì | Solo community |
| Frequenza aggiornamenti | Settimanale | Due volte l'anno |
| Gestione infrastruttura | Gestita | A tuo carico |
La versione cloud usa un modello in abbonamento. Consulta la pagina prezzi di Plausible per le tariffe correnti. Il self-hosting ti costa solo le risorse del VPS.
Quali sono i requisiti di sistema per il self-hosting di Plausible?
ClickHouse è il componente più esigente. Necessita di almeno 2 GB di RAM a riposo e ne consuma di più durante query complesse su grandi dataset. La CPU deve supportare le istruzioni SSE 4.2 (tutti i processori x86_64 moderni lo fanno; ARM64 con NEON funziona ugualmente). Dimensiona il tuo VPS di conseguenza.
| Risorsa | Minimo | Consigliato |
|---|---|---|
| RAM | 2 GB | 4 GB |
| CPU | 1 vCPU (SSE 4.2) | 2 vCPU |
| Disco | 10 GB | 20 GB+ |
| Docker | 20.10+ | Ultima versione stabile |
| Docker Compose | v2.x | Ultima versione stabile |
La crescita del disco dipende dal traffico. Prevedi circa 1 GB ogni 1-2 milioni di pagine visualizzate archiviate in ClickHouse. Con volumi di traffico bassi (sotto 100.000 pagine visualizzate al mese), l'utilizzo del disco è trascurabile.
Come si installa Plausible Analytics con Docker Compose?
Clona il repository ufficiale della Community Edition al tag v3.2.0, configura le variabili d'ambiente e avvia i container. L'intero processo richiede circa cinque minuti.
Clona il repository:
git clone -b v3.2.0 --single-branch https://github.com/plausible/community-edition plausible-ce
cd plausible-ce
Questo ti dà il compose.yml, i file di configurazione di ClickHouse e un README.
Come si configurano le variabili d'ambiente?
Crea un file .env nella directory plausible-ce. Due variabili sono obbligatorie. Le altre sono opzionali, ma alcune sono fortemente consigliate.
Genera prima i secret:
openssl rand -base64 48
Questo produce una stringa di 64 caratteri. Copiala per SECRET_KEY_BASE.
Genera una chiave separata per la crittografia TOTP:
openssl rand -base64 32
Ora crea il file .env:
cat > .env << 'EOF'
BASE_URL=https://plausible.example.com
SECRET_KEY_BASE=<your-64-char-secret>
TOTP_VAULT_KEY=<your-32-char-key>
DISABLE_REGISTRATION=invite_only
# SMTP for email reports and password resets
MAILER_EMAIL=plausible@example.com
SMTP_HOST_ADDR=mail.example.com
SMTP_HOST_PORT=587
SMTP_USER_NAME=plausible@example.com
SMTP_USER_PWD=<your-smtp-password>
SMTP_HOST_SSL_ENABLED=false
EOF
Blocca i permessi del file dato che contiene secret:
chmod 600 .env
ls -la .env
-rw------- 1 root root 412 Mar 20 10:00 .env
Cosa fa ogni variabile:
- BASE_URL: L'URL pubblico dove Plausible è raggiungibile. Deve corrispondere alla configurazione del reverse proxy.
- SECRET_KEY_BASE: Crittografa le sessioni e genera chiavi derivate. Minimo 64 byte. Non condividerla mai.
- TOTP_VAULT_KEY: Crittografa i secret dell'autenticazione a due fattori con AES256-GCM. Se omessa, viene derivata da
SECRET_KEY_BASEvia PBKDF2, ma impostarla esplicitamente è più sicuro per la rotazione delle chiavi. - DISABLE_REGISTRATION: Imposta su
invite_only(predefinito) otruedopo aver creato il tuo account. Impedisce a sconosciuti di registrarsi sulla tua istanza. - Variabili SMTP: Necessarie per report via email, reset password e email di invito. Senza SMTP, Plausible funziona ma le funzionalità email sono disabilitate.
Come si configura un reverse proxy con TLS per Plausible?
Plausible ascolta sulla porta 8000 per impostazione predefinita. Il reverse proxy inoltra il traffico HTTPS ad essa. Se hai già Caddy o Traefik in funzione da Traefik vs Caddy vs Nginx: reverse proxy Docker a confronto, aggiungi Plausible come nuovo upstream.
Crea un compose.override.yml per connettere Plausible alla rete del reverse proxy:
services:
plausible:
networks:
- proxy
- default
networks:
proxy:
external: true
Se usi Caddy, aggiungi questo al tuo Caddyfile:
plausible.example.com {
reverse_proxy plausible:8000
}
Se usi Traefik, aggiungi le label all'override:
services:
plausible:
labels:
- "traefik.enable=true"
- "traefik.http.routers.plausible.rule=Host(`plausible.example.com`)"
- "traefik.http.routers.plausible.tls.certresolver=letsencrypt"
- "traefik.http.services.plausible.loadbalancer.server.port=8000"
networks:
- proxy
- default
networks:
proxy:
external: true
In alternativa, Plausible ha il supporto Let's Encrypt integrato. Imposta HTTP_PORT=80 e HTTPS_PORT=443 nel file .env, poi esponi queste porte nell'override:
services:
plausible:
ports:
- 80:80
- 443:443
Questo approccio è più semplice ma significa che Plausible gestisce TLS direttamente, il che può creare conflitti se altri servizi condividono lo stesso server.
Avviare i container
docker compose up -d
Si avviano tre container: plausible_db (PostgreSQL 16), plausible_events_db (ClickHouse 24.12) e plausible (l'applicazione web). Il container Plausible esegue automaticamente le migrazioni del database all'avvio.
Verifica che tutti e tre siano operativi:
docker compose ps
NAME IMAGE STATUS
plausible ghcr.io/plausible/community-edition:v3.2.0 Up 30s (healthy)
plausible_db postgres:16-alpine Up 35s (healthy)
plausible_events_db clickhouse/clickhouse-server:24.12-alpine Up 35s (healthy)
Tutti e tre dovrebbero mostrare (healthy). Se ClickHouse mostra (health: starting), attendi un altro minuto. Esegue un healthcheck tramite wget sulla sua interfaccia HTTP.
Creare l'account amministratore
Apri https://plausible.example.com nel browser. Vedrai il modulo di registrazione. Crea il tuo account. Con DISABLE_REGISTRATION=invite_only, i nuovi utenti possono registrarsi solo se li inviti esplicitamente dalla dashboard.
Dopo la registrazione, blocca completamente le registrazioni se sei l'unico utente:
Modifica .env e cambia:
DISABLE_REGISTRATION=true
Poi riavvia:
docker compose up -d
Come si aggiunge lo script di tracciamento Plausible al proprio sito?
Dopo il login, clicca su "Add a website" e inserisci il tuo dominio. Plausible genera uno snippet di tracciamento. Il tag script predefinito ha questo aspetto:
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.js"></script>
Sostituisci plausible.example.com con l'URL effettivo della tua istanza Plausible. Aggiungi questo tag nel <head> di ogni pagina che vuoi tracciare.
Come si aggiunge Plausible a un sito HTML statico?
Incolla il tag script direttamente nel <head> del tuo HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Site</title>
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.js"></script>
</head>
<body>
<!-- content -->
</body>
</html>
Per i generatori di siti statici (Hugo, Jekyll, 11ty), aggiungi il tag script nel template base o nel partial head.
Come si aggiunge Plausible a un sito WordPress?
Il plugin ufficiale Plausible Analytics per WordPress (v2.5.4, oltre 10.000 installazioni attive) gestisce tutto dalla dashboard di WordPress.
- Installa il plugin: Plugin > Aggiungi nuovo > Cerca "Plausible Analytics"
- Vai su Impostazioni > Plausible Analytics
- Inserisci l'URL della tua istanza self-hosted (es.
https://plausible.example.com) - Inserisci il nome di dominio da tracciare
- Salva
Il plugin inietta automaticamente lo script di tracciamento. Supporta anche il tracciamento delle conversioni WooCommerce e il tracciamento automatico dell'invio di moduli per Contact Form 7, WPForms e Ninja Forms.
Come si aggiunge Plausible a un'app Next.js?
Usa il pacchetto next-plausible (v3.12.5, 36.000 download settimanali).
npm i next-plausible
Per l'App Router (Next.js 13+), aggiungi il provider nel layout root:
import PlausibleProvider from "next-plausible";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<head>
<PlausibleProvider
domain="yoursite.com"
customDomain="https://plausible.example.com"
selfHosted
/>
</head>
<body>{children}</body>
</html>
);
}
Per tracciare eventi personalizzati nei componenti, usa l'hook usePlausible:
"use client";
import { usePlausible } from "next-plausible";
export default function SignupButton() {
const plausible = usePlausible();
return (
<button onClick={() => plausible("Signup")}>
Sign up
</button>
);
}
Come si aggiunge Plausible a una single-page application?
Per React, Vue, Svelte o qualsiasi SPA, aggiungi il tag script nel tuo index.html. Plausible traccia automaticamente i cambiamenti di rotta tramite la History API. Non serve configurazione aggiuntiva.
Se la tua SPA usa routing basato su hash (/#/path), usa l'estensione hash:
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.hash.js"></script>
Come si tracciano eventi personalizzati e obiettivi in Plausible?
Gli eventi personalizzati permettono di tracciare azioni oltre le visualizzazioni di pagina: clic sui pulsanti, invio di moduli, download di file, registrazioni. Plausible offre due metodi: un approccio no-code con classi CSS e un'API JavaScript per il tracciamento dinamico.
Prima di tutto, abilita lo script migliorato che supporta gli eventi personalizzati. Sostituisci la sorgente dello script predefinito:
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.tagged-events.js"></script>
Metodo classi CSS (senza JavaScript)
Aggiungi una classe CSS nel formato plausible-event-name=EventName a qualsiasi elemento HTML:
<a href="/signup" class="plausible-event-name=Signup">Create Account</a>
<button class="plausible-event-name=Download+PDF">Download Report</button>
<form class="plausible-event-name=Contact+Form+Submit">
<!-- form fields -->
</form>
Usa + per gli spazi nei nomi degli eventi. Alcuni CMS (Webflow) sostituiscono = con -. In quel caso, usa un doppio trattino --: plausible-event-name--Signup.
API JavaScript per eventi dinamici
Chiama la funzione plausible() direttamente per eventi che necessitano di logica condizionale o proprietà dinamiche:
// Simple event
plausible("Signup");
// Event with custom properties
plausible("Download", {
props: { format: "PDF", document: "annual-report" }
});
// Event with a callback (useful for redirects)
plausible("Outbound Link", {
props: { url: "https://example.com" },
callback: () => { window.location = "https://example.com"; }
});
Creare l'obiettivo nella dashboard
Gli eventi non compaiono nella dashboard finché non crei un obiettivo corrispondente. Vai su Site Settings > Goals > Add Goal. Seleziona "Custom event" e inserisci il nome esatto dell'evento (es. Signup). Il nome è case-sensitive e deve corrispondere al codice.
Come si usa la Plausible Stats API?
Plausible include una Stats API (v2) per l'accesso programmatico ai dati analitici. Sulla tua istanza self-hosted, l'URL base dell'API è https://plausible.example.com/api/v2/query.
Crea una chiave API: vai su Account Settings > API Keys > New API Key > Stats API.
Interroga il conteggio visitatori degli ultimi 7 giorni:
curl --request POST \
--header 'Authorization: Bearer YOUR-API-KEY' \
--header 'Content-Type: application/json' \
--url 'https://plausible.example.com/api/v2/query' \
--data '{
"site_id": "yoursite.com",
"metrics": ["visitors", "pageviews", "bounce_rate"],
"date_range": "7d"
}'
{
"results": [
{
"metrics": [1423, 3847, 42],
"dimensions": []
}
],
"query": {
"site_id": "yoursite.com",
"metrics": ["visitors", "pageviews", "bounce_rate"],
"date_range": ["2026-03-13", "2026-03-20"]
}
}
Dettaglio visitatori per pagina:
curl --request POST \
--header 'Authorization: Bearer YOUR-API-KEY' \
--header 'Content-Type: application/json' \
--url 'https://www.example.com/api/v2/query' \
--data '{
"site_id": "yoursite.com",
"metrics": ["visitors", "pageviews"],
"date_range": "30d",
"dimensions": ["event:page"],
"pagination": {"limit": 5}
}'
L'API supporta filtri, dimensioni temporali (time:day, time:month) e ordinamento. Il rate limit è di 600 richieste all'ora. Consulta il riferimento completo della Stats API per tutte le metriche e dimensioni disponibili.
Come si configurano i report via email?
I report via email richiedono una configurazione SMTP funzionante nel file .env (descritta nella sezione di setup sopra). Una volta configurato SMTP, qualsiasi utente può abilitare report settimanali o mensili dalla dashboard Plausible.
Vai su Site Settings > Email Reports. Aggiungi gli indirizzi dei destinatari. Plausible invia un riepilogo di visitatori, pagine più visitate e fonti di traffico con la frequenza scelta.
Se le email non arrivano, controlla i log del container Plausible:
docker compose logs plausible | grep -i mail
Problemi comuni: porta SMTP errata (usa 587 per STARTTLS, 465 per TLS implicito con SMTP_HOST_SSL_ENABLED=true), o errori di autenticazione.
Come si fa il backup di un'istanza Plausible self-hosted?
Plausible archivia i dati in due database e un volume. Perdere uno qualsiasi di essi significa perdere dati. Fai il backup di tutti e tre.
| Dati | Storage | Metodo di backup |
|---|---|---|
| Account utente, configurazione siti | PostgreSQL | pg_dump |
| Eventi analitici | ClickHouse | Backup volume o comando BACKUP |
| Certificati, upload | Volume plausible-data |
Copia volume |
Backup di PostgreSQL
docker compose exec plausible_db pg_dump -U postgres plausible_db | gzip > backup-postgres-$(date +%F).sql.gz
Backup di ClickHouse
ClickHouse 24.12 supporta il comando BACKUP nativamente. Eseguilo nel container:
docker compose exec plausible_events_db clickhouse-client \
--query "BACKUP DATABASE plausible_events_db TO Disk('backups', 'plausible-$(date +%F).zip')"
Se il disco backups non è configurato, usa un backup a livello di volume:
docker compose stop plausible_events_db
docker run --rm \
-v plausible-ce_event-data:/source:ro \
-v $(pwd)/backups:/backup \
alpine tar czf /backup/clickhouse-$(date +%F).tar.gz -C /source .
docker compose start plausible_events_db
Questo ferma brevemente ClickHouse. Per backup senza downtime, configura il disco backups in ClickHouse o usa clickhouse-backup.
Automatizzare il backup
Crea uno script in /opt/plausible-backup.sh:
#!/bin/bash
set -euo pipefail
BACKUP_DIR=/opt/backups/plausible
mkdir -p "$BACKUP_DIR"
cd /opt/plausible-ce
# PostgreSQL
docker compose exec -T plausible_db pg_dump -U postgres plausible_db \
| gzip > "$BACKUP_DIR/postgres-$(date +%F).sql.gz"
# ClickHouse volume
docker run --rm \
-v plausible-ce_event-data:/source:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf "/backup/clickhouse-$(date +%F).tar.gz" -C /source .
# Plausible data volume
docker run --rm \
-v plausible-ce_plausible-data:/source:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf "/backup/plausible-data-$(date +%F).tar.gz" -C /source .
# Rotate: keep 14 days
find "$BACKUP_DIR" -name "*.gz" -mtime +14 -delete
echo "Backup complete: $(ls -lh $BACKUP_DIR/*$(date +%F)*)"
chmod 700 /opt/plausible-backup.sh
Programmalo con cron per l'esecuzione giornaliera:
crontab -e
Aggiungi:
0 3 * * * /opt/plausible-backup.sh >> /var/log/plausible-backup.log 2>&1
Per approfondire le strategie di backup dei volumi Docker, consulta Backup e ripristino dei volumi Docker su un VPS.
Come si aggiorna Plausible Community Edition in sicurezza?
Plausible CE viene rilasciato due volte l'anno. Blocca la versione su un tag specifico in compose.yml per aggiornamenti prevedibili. La configurazione predefinita blocca già la versione v3.2.0.
Strategie di pinning della versione:
| Livello | Esempio di tag | Cosa si aggiorna automaticamente |
|---|---|---|
| Patch (più sicuro) | v3.2.0 |
Nulla. Solo aggiornamenti manuali. |
| Minor | v3.2 |
Release patch (bugfix) |
| Major | v3 |
Release minor e patch |
Consigliato: blocca a livello di patch e aggiorna manualmente dopo aver letto le note di rilascio.
Procedura di aggiornamento
-
Leggi le note di rilascio per i breaking change
-
Fai il backup dei database (esegui lo script di backup sopra)
-
Scarica la nuova versione:
cd /opt/plausible-ce
git fetch --tags
git checkout v3.3.0 # replace with the target version
- Avvia i container aggiornati:
docker compose up -d
Plausible esegue automaticamente le migrazioni del database all'avvio. Monitora i log durante il primo avvio:
docker compose logs -f plausible
Cerca [info] Migrations up to XXXXXXXX applied successfully nell'output. Se vedi errori di migrazione, non eliminare i vecchi dati. Consulta la pagina wiki dell'upgrade per istruzioni specifiche per versione.
- Pulisci la vecchia immagine:
docker image prune -f
Le patch di sicurezza non vengono backportate alle versioni precedenti. Iscriviti alle notifiche di rilascio su GitHub: vai al repository, clicca su Watch > Custom > Releases.
Plausible self-hosted è conforme al GDPR senza cookie?
Sì. Plausible non imposta cookie. Non raccoglie né archivia dati personali. I visitatori unici vengono contati usando un hash dell'indirizzo IP del visitatore combinato con la stringa User-Agent. Questo hash viene ruotato ogni 24 ore e non viene mai archiviato in forma grezza. L'indirizzo IP grezzo viene scartato dopo l'hashing.
Questo significa:
- Nessun banner di consenso cookie necessario ai sensi di GDPR, CCPA o PECR
- Nessun trattamento di dati personali, quindi i requisiti di base giuridica dell'articolo 6 del GDPR non si applicano
- Il self-hosting garantisce che i dati non lascino mai il tuo server e non passino mai attraverso un responsabile del trattamento terzo
- Rimani l'unico titolare del trattamento, senza necessità di accordi con responsabili del trattamento per l'analytics
Se ospiti il tuo VPS nell'UE (i server Virtua Cloud si trovano in data center europei), i dati analitici restano nell'UE. Nessun problema di trasferimento legato a Schrems II.
Per questo molti sviluppatori indipendenti e attenti alla privacy abbandonano Google Analytics. Niente banner di consenso, niente frizione per i visitatori e niente accordi di trattamento dati da gestire.
Monitorare il consumo di risorse di ClickHouse
ClickHouse è il componente più esigente in termini di risorse. A riposo con traffico basso, usa circa 500 MB di RAM. Durante query su grandi dataset, può salire a 2-3 GB. Se il tuo VPS ha solo 2 GB di RAM totale, potresti incorrere in OOM kill nei periodi di carico.
Monitora l'utilizzo della memoria:
docker stats plausible_events_db --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM %
a1b2c3d4e5f6 plausible_events_db 0.50% 487MiB / 3.84GiB 12.38%
La configurazione di ClickHouse fornita con Plausible CE include già override per risorse limitate (tramite low-resources.xml e default-profile-low-resources-overrides.xml). Questi limitano l'utilizzo della memoria per merge e query.
Se devi ottimizzare ulteriormente, crea un file clickhouse/custom.xml di override e montalo in compose.override.yml. Per i limiti di risorse in Docker Compose, consulta Limiti di risorse, healthcheck e politiche di riavvio in Docker Compose.
Controlla i log di ClickHouse per eventuali avvisi:
docker compose logs plausible_events_db | grep -i "memory\|oom"
Qualcosa non funziona?
I container non partono: Controlla docker compose logs <service>. Cause comuni: conflitti di porte, variabili .env mancanti, ClickHouse che non supera il controllo SSE 4.2 su CPU datate.
"Bad Request" nella pagina di login: La tua BASE_URL non corrisponde all'URL che stai usando. Plausible verifica l'header origin rispetto a BASE_URL per prevenire attacchi CSRF.
Lo script di tracciamento non registra le visite: Apri gli strumenti di sviluppo del browser, controlla la scheda Rete per le richieste verso /api/event. Una risposta 202 indica che l'evento è stato accettato. Se vedi errori CORS, il reverse proxy sta rimuovendo degli header. Assicurati che il proxy passi l'header Host.
I report via email non vengono inviati: Verifica le credenziali SMTP. Controlla i log con docker compose logs plausible | grep -i smtp. Testa il server SMTP indipendentemente con swaks o openssl s_client.
ClickHouse terminato dall'OOM killer: Il VPS non ha abbastanza RAM. Fai l'upgrade ad almeno 4 GB, oppure riduci max_memory_usage in un override di configurazione ClickHouse.
La dashboard mostra zero visitatori dopo il setup: Lo script di tracciamento potrebbe essere bloccato da un ad blocker. Considera di fare il proxy dello script attraverso il tuo dominio principale. La documentazione di Plausible lo chiama proxy setup.
Per monitorare l'uptime della tua istanza Plausible, consulta Self-hosting di Uptime Kuma e Beszel su un VPS con Docker Compose.