Dashboard Plausible Analytics self-hosted care ruleaza in Docker pe un VPS
Self-hosting

Plausible self-hosted cu Docker: statistici web fara cookie-uri

Daca ai pus vreodata Google Analytics pe un site mic, stii pachetul complet: un script greu venit de la terti, un banner de cookie-uri care enerveaza fiecare vizitator, un manager de consimtamant de configurat si un dashboard atat de complicat incat ajungi oricum sa te uiti la un singur numar. Pentru majoritatea blogurilor, magazinelor online si site-urilor de firma, intrebarile sunt mult mai simple: cati oameni au intrat, de unde au venit, ce pagini au citit si daca a mers campania de saptamana trecuta? Plausible raspunde exact la ele, cu un script de tracking de aproximativ un kilobyte, fara cookie-uri si cu un dashboard pe o singura pagina. Iar cu Community Edition totul ruleaza pe propriul tau VPS, deci datele nu pleaca de pe un server pe care il controlezi tu.

Plausible este dezvoltat de o echipa mica din UE, pe plausible.io , iar varianta self-hosted, Community Edition (CE), se afla pe github.com/plausible/community-edition , sub licenta AGPLv3. In ghidul asta instalam Plausible self-hosted cu Docker pe un VPS proaspat cu Debian 13 sau Ubuntu 24.04: aplicatia cu bazele ei de date PostgreSQL si ClickHouse, Caddy ca reverse proxy cu HTTPS, mai multe site-uri urmarite dintr-o singura instanta si SMTP, ca Plausible sa-ti trimita rapoarte saptamanale si lunare pe email. Explicam fiecare pas, deci nu trebuie sa fii sysadmin cu experienta ca sa-l urmezi.

Ce este, de fapt, Plausible Community Edition

Statisticile web (web analytics) inseamna sa numeri si sa descrii vizitele de pe site-ul tau. Un mic fragment JavaScript ruleaza in browserul fiecarui vizitator si trimite un “eveniment” (o afisare de pagina, un click pe butonul de inscriere) catre un server de statistici, care il salveaza si transforma milioane de evenimente in grafice.

Plausible face asta fara cookie-uri si fara sa stocheze date personale. In loc sa puna un ID unic in browserul vizitatorului, calculeaza pe server un identificator zilnic din adresa IP, user agent-ul browserului, domeniul site-ului si un “salt” aleator care se schimba la fiecare 24 de ore. Rezultatul este un hash intr-un singur sens: Plausible stie ca doua afisari de azi vin de la acelasi vizitator, dar nu poate urmari pe nimeni de la o zi la alta sau intre site-uri diferite, iar adresa IP bruta nu ajunge niciodata pe disc. De aceea multi proprietari de site-uri il folosesc fara banner de consimtamant pentru cookie-uri, desi e bine sa verifici mereu ce spun regulile locale si consultantul tau juridic pentru cazul tau concret.

Community Edition este acelasi produs de baza ca Plausible Cloud (varianta platita), impachetat pentru self-hosting. Primesti dashboard-ul, obiective si evenimente custom, urmarirea campaniilor UTM, rapoarte pe email, linkuri de partajare, export CSV si importuri. Cateva functii premium din cloud nu sunt incluse, iar versiunile noi apar mai rar, asa ca verifica comparatia de pe site-ul proiectului daca depinzi de ceva anume.

De ce are nevoie de doua baze de date

Plausible foloseste doua baze de date diferite, iar daca intelegi de ce, restul instalarii devine mult mai putin misterios:

  • PostgreSQL este o baza de date relationala clasica. Tine datele “mici, dar importante”: conturile de utilizator, lista site-urilor, obiectivele, setarile, invitatiile.
  • ClickHouse este o baza de date pe coloane, construita pentru analiza. In loc sa stocheze fiecare rand la un loc, stocheaza fiecare coloana separat si comprimat, asa ca o intrebare de tipul “afisari pe zi in ultimul an” citeste doar coloanele de care are nevoie. Asa reuseste un VPS mic sa raspunda la interogarile dashboard-ului peste milioane de evenimente intr-o fractiune de secunda.

Amandoua ruleaza in containere separate. Un container este un pachet izolat care contine o aplicatie cu toate bibliotecile ei, pornit dintr-o imagine, deci ruleaza la fel pe orice server Linux. Docker Compose este unealta care porneste impreuna mai multe containere inrudite, pe baza unui singur fisier YAML, si le leaga intr-o retea privata.

Cum se leaga piesele unui stack Plausible self-hosted cu Docker

VPS DreamServer (Debian 13 / Ubuntu 24.04)Vizitatoripe site-urile taleTu, adminuldashboardServer SMTPrapoarte, invitatiiufw22, 80, 443doar hostCaddyHTTPS + certificatereverse proxyufw filtreaza doar porturilehost-ului. Portul 8000 epublicat doar pe 127.0.0.1.Docker Compose (ocoleste ufw)Aplicatia Plausible CEport 8000 doar pe 127.0.0.1PostgreSQLuseri, site-uriClickHouseevenimentedb-dataevent-dataplausible-data (fisiere app)SMTP de iesire (587)
Traficul intra prin Caddy, singurul serviciu expus pe 80/443; Plausible asculta doar pe 127.0.0.1, iar ambele baze de date raman in reteaua privata Docker, cu datele in volume.

Iata drumul unei cereri de tracking. Un vizitator deschide unul dintre site-urile tale, fragmentul de cod incarca script.js de pe subdomeniul de statistici si trimite un eveniment mic prin HTTPS, pe portul 443. Un port este, simplu spus, o usa numerotata a serverului: 443 este cea standard pentru HTTPS, 80 pentru HTTP simplu si 22 pentru SSH.

Pe VPS, Caddy este singurul program care asculta pe porturile 80 si 443. El este un reverse proxy: primeste conexiunile din internet, se ocupa de certificatul TLS (obtinut automat de la Let’s Encrypt) si trimite fiecare cerere mai departe catre containerul Plausible, care asculta doar pe 127.0.0.1:8000. Adresa 127.0.0.1 inseamna “doar masina asta”, deci nimeni din internet nu poate ajunge direct la portul 8000.

Firewall-ul, ufw, protejeaza serviciile care ruleaza direct pe host (SSH si Caddy). Nu protejeaza containerele: cand Docker publica un port, isi scrie propriile reguli iptables, care ocolesc ufw. Exact din motivul asta legam Plausible de 127.0.0.1, in loc sa ne bazam pe ufw ca sa-l blocheze. PostgreSQL si ClickHouse nu sunt publicate deloc; doar containerul Plausible vorbeste cu ele, prin reteaua privata Docker. Datele lor stau in volume, foldere gestionate de Docker care supravietuiesc repornirilor si actualizarilor.

De ce ai nevoie

  • Un VPS KVM cu minim 2 vCPU si 2 GB RAM (4 GB e mai confortabil cand urmaresti cateva site-uri cu trafic) si cel putin 20 GB de disc. Un procesor x86-64 trebuie sa suporte setul de instructiuni SSE 4.2 (practic toate cele moderne il au), sau poti folosi ARM64.
  • Debian 13 sau Ubuntu 24.04 proaspat instalat, cu un utilizator cu drepturi sudo si acces prin SSH.
  • Un domeniu la care poti edita inregistrarile DNS. In tot ghidul folosim stats.example.com; inlocuieste-l peste tot cu subdomeniul tau.
  • Optional, dar recomandat: datele SMTP de la furnizorul tau de email, pentru rapoarte, invitatii si resetari de parola.
  • Cam 30 pana la 45 de minute.

O observatie despre serverele bazate pe containere: un VPS KVM este alegerea potrivita aici. Intr-un container LXC neprivilegiat, Docker merge doar daca nesting-ul e activat, ClickHouse poate esua cand incearca sa-si mareasca limita de fisiere deschise (“operation not permitted”), iar fisierele swap nu pot fi activate. Se poate face sa mearga, dar iti vei petrece timpul luptandu-te cu platforma in loc sa citesti statistici.

Instalarea Plausible CE in 8 pasi1Pregatire VPSupdate, swap, DNSufw pe 22, 80, 4432Docker Enginerepo apt oficialfisier docker.sources3Descarca CEultimul tag releasegit clone repo CE4Fisierul .envBASE_URL, cheieoverride port 80005Pornire stackdocker compose up -dverifica /api/health6Caddy + HTTPSproxy in CaddyfileTLS automat7Site-uri noicont de adminsnippet per site8Rapoarte SMTPvariabile MAILERrapoarte saptamanale
Cei opt pasi ai ghidului; numerele corespund titlurilor de la Pasul 1 pana la Pasul 8 de mai jos.

Pasul 1: Pregatim VPS-ul, DNS-ul si firewall-ul

Mai intai aducem sistemul la zi:

sudo apt update && sudo apt full-upgrade -y

Pe Ubuntu, verifici daca e nevoie de restart cu [ -f /var/run/reboot-required ] && echo "Reboot needed". Debian nu creeaza mereu acel fisier, asa ca pe Debian dai restart daca actualizarea a instalat un pachet linux-image nou. Ruleaza sudo reboot si reconecteaza-te dupa un minut.

Apoi confirmam ca procesorul poate rula ClickHouse si vedem cata memorie avem:

uname -m
grep -m1 -o -w 'sse4_2' /proc/cpuinfo || echo "No SSE 4.2 found"
nproc
free -h

Pe x86_64 vrei sa vezi afisat sse4_2. Pe aarch64 (ARM64) verificarea afiseaza “No SSE 4.2 found”, ceea ce e in regula acolo, pentru ca procesoarele ARM folosesc setul de instructiuni NEON. nproc arata numarul de vCPU, iar free -h memoria RAM si swap-ul.

Daca ai 2 GB RAM si free -h nu arata swap, adauga un fisier swap de 2 GB ca plasa de siguranta pentru varfurile de memorie (nu functioneaza in LXC):

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Acum DNS-ul. In panoul furnizorului tau de DNS, creeaza o inregistrare A pentru stats.example.com care sa indice adresa IPv4 a VPS-ului (plus o inregistrare AAAA pentru IPv6, daca o folosesti). Dupa cateva minute, verifica direct de pe VPS:

getent hosts stats.example.com

Rezultatul trebuie sa afiseze IP-ul VPS-ului. Caddy poate obtine certificatul doar dupa ce asta e corect.

La final, firewall-ul. Ubuntu vine cu ufw instalat, dar inactiv, in timp ce Debian de obicei nu il include, asa ca il instalam in ambele cazuri. Permite SSH inainte sa activezi firewall-ul, altfel iti tai singur accesul:

sudo apt install -y ufw
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Daca serverul SSH asculta pe un port nestandard, inlocuieste OpenSSH cu portul respectiv, de exemplu sudo ufw allow 2222/tcp. In status trebuie sa vezi 22 (sau portul tau), 80 si 443 marcate ALLOW IN.

Pasul 2: Instalam Docker Engine si pluginul Compose

Pachetele Docker din depozitele distributiei sunt adesea mai vechi, asa ca folosim depozitul apt oficial Docker, descris in formatul actual deb822. Prima linie instaleaza si cateva unelte de care avem nevoie mai tarziu (git pentru descarcarea Plausible, openssl pentru generarea unei chei secrete):

sudo apt install -y ca-certificates curl git openssl
sudo install -m 0755 -d /etc/apt/keyrings
. /etc/os-release
sudo curl -fsSL "https://download.docker.com/linux/${ID}/gpg" -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/${ID}
Suites: ${VERSION_CODENAME}
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Linia . /etc/os-release incarca doua variabile: ID (debian sau ubuntu) si VERSION_CODENAME (trixie sau noble), deci acelasi bloc merge pe ambele sisteme. Daca ai urmat in trecut un ghid mai vechi care a creat /etc/apt/sources.list.d/docker.list, sterge acel fisier ca sa nu primesti avertismente de surse duplicate.

Verifica faptul ca totul functioneaza:

sudo docker run --rm hello-world
sudo docker compose version

Trebuie sa vezi mesajul “Hello from Docker!” si o versiune de Compose care incepe cu v2. In ghidul asta punem sudo in fata comenzilor Docker, in loc sa adaugam utilizatorul in grupul docker, pentru ca apartenenta la acel grup inseamna practic acces de root.

Pasul 3: Descarcam Plausible Community Edition

Plausible CE este distribuit ca un mic depozit Git care contine un compose.yml testat si cateva fisiere de configurare pentru ClickHouse. Fiecare versiune este un tag Git, iar noi vrem mereu cea mai noua. Blocul de mai jos intreaba API-ul GitHub care este ultimul tag publicat si cloneaza exact acea versiune:

cd ~
CE_TAG=$(curl -fsSL https://api.github.com/repos/plausible/community-edition/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+')
echo "Latest Plausible CE release: $CE_TAG"
git clone -b "$CE_TAG" --single-branch https://github.com/plausible/community-edition plausible-ce
cd plausible-ce
ls

Linia echo ar trebui sa afiseze un tag de forma v3.x.y. Daca nu afiseaza nimic (de exemplu din cauza unei limite de cereri la API), deschide pagina de release-uri , copiaza manual cel mai nou tag si ruleaza linia git clone cu el. Git va pomeni de un “detached HEAD”: e normal cand descarci un tag in loc de o ramura.

ls trebuie sa arate compose.yml, README.md si un folder clickhouse. Uita-te si la imaginile folosite de aceasta versiune:

grep 'image:' compose.yml

Vei vedea imaginea Plausible fixata pe aceeasi versiune ca tag-ul, plus imagini PostgreSQL si ClickHouse cu versiuni precise. Lasa-le exact asa. Echipa Plausible testeaza fiecare versiune cu acele baze de date, iar daca muti de mana PostgreSQL pe o versiune majora mai noua, strici directorul de date existent, pentru ca upgrade-urile majore de PostgreSQL cer dump si restore. Nu le inlocui nici cu :latest: un pull facut nesupravegheat te poate muta pe o combinatie netestata.

Pasul 4: Configuram fisierul .env

Plausible isi citeste setarile din variabile de mediu, pe care Docker Compose le incarca dintr-un fisier numit .env din folderul proiectului. Il cream cu cele patru setari de care avem nevoie:

cat > .env <<EOF
BASE_URL=https://stats.example.com
SECRET_KEY_BASE=$(openssl rand -base64 48)
HTTP_PORT=8000
DISABLE_REGISTRATION=invite_only
EOF
chmod 600 .env
cat .env

Ce face fiecare linie:

  • BASE_URL este adresa publica a instantei, cu https:// si fara slash la final. Plausible o foloseste ca sa construiasca linkurile din emailuri si din fragmentul de tracking, deci trebuie sa fie exact subdomeniul tau.
  • SECRET_KEY_BASE este o cheie aleatoare de 64 de caractere, folosita pentru semnarea sesiunilor si criptarea datelor sensibile. Partea $(openssl rand -base64 48) o genereaza pentru tine. Nu o da nimanui si nu o schimba dupa instalare, altfel toata lumea e delogata, iar setarile criptate devin ilizibile.
  • HTTP_PORT=8000 face ca Plausible sa asculte pe portul 8000 in interiorul containerului. Nu setam intentionat HTTPS_PORT, ca gestionarea interna a certificatelor din Plausible sa ramana oprita si sa se ocupe Caddy de TLS.
  • DISABLE_REGISTRATION=invite_only inseamna ca, dupa ce creezi primul cont, nimeni altcineva nu se mai poate inregistra fara invitatie de la tine. Foloseste true ca sa blochezi complet inregistrarea.

chmod 600 face fisierul citibil doar de utilizatorul tau, lucru important pentru ca in el va sta si parola SMTP.

Acum ii spunem lui Docker sa publice portul 8000, dar doar pe adresa de loopback. In loc sa modificam compose.yml (ar intra in conflict cu actualizarile viitoare), cream compose.override.yml, un fisier pe care Docker Compose il combina automat peste compose.yml:

cat > compose.override.yml <<'EOF'
services:
  plausible:
    ports:
      - "127.0.0.1:8000:8000"
EOF

Formatul este adresa_host:port_host:port_container. Daca ai scrie doar 8000:8000, portul ar fi publicat pe toate interfetele, iar pentru ca Docker ocoleste ufw, portul 8000 ar fi accesibil din tot internetul, prin HTTP necriptat.

Pasul 5: Pornim stack-ul Plausible in Docker

E momentul sa pornim totul:

sudo docker compose up -d
sudo docker compose ps

La prima rulare se descarca trei imagini (cateva sute de megabytes), apoi pornesc PostgreSQL si ClickHouse, se asteapta verificarile lor de sanatate (health checks), se creeaza bazele de date si se ruleaza migrarile. Dupa un minut sau doua, docker compose ps trebuie sa arate plausible, plausible_db si plausible_events_db cu starea Up, iar cele doua baze de date si cu healthy.

Urmareste log-ul aplicatiei ca sa vezi pornirea:

sudo docker compose logs -f plausible

Vei vedea mesaje despre migrari, urmate de o linie care spune ca endpoint-ul web ruleaza. Apasa Ctrl+C ca sa nu mai urmaresti log-ul; containerele raman pornite. Apoi testeaza aplicatia local, fara sa treci prin proxy:

curl -s http://127.0.0.1:8000/api/health; echo

Ar trebui sa primesti un raspuns JSON scurt in care postgres si clickhouse apar cu ok. Daca comanda se blocheaza sau intoarce o eroare, mai asteapta un minut si verifica din nou log-urile: ClickHouse poate fi lent la prima pornire.

Cat RAM consuma de fapt?

Ruleaza sudo docker stats --no-stream ca sa vezi memoria folosita de fiecare container. Pe o instanta mica, care urmareste cateva site-uri cu trafic redus, te poti astepta la valori aproximativ ca acestea:

RAM aproximativ pe componenta (in repaus, site mic)Total: aprox. 0.9 GB0150300450600RAM folosit (MB, aprox.)~550 MB~260 MB~60 MB~25 MBClickHouseAplicatia PlausiblePostgreSQLCaddy (host)Componenta (valorile variaza cu traficul si versiunea)
Consumul aproximativ de memorie al unei instante Plausible CE mici, in repaus; ClickHouse domina, de aceea 2 GB RAM sunt minimul practic.

ClickHouse este cel mai mare consumator, si e normal sa fie asa: tine cache-uri in memorie ca interogarile sa fie rapide. Depozitul monteaza deja o configuratie low-resources.xml care ii tine pofta in limite rezonabile pe servere mici. De aceea recomandam minim 2 GB RAM si 4 GB cand site-urile cresc sau cand mai rulezi si alte servicii pe acelasi VPS.

Pasul 6: Punem Caddy in fata, cu HTTPS

Caddy este un server web care obtine si reinnoieste singur certificatele Let’s Encrypt. Atat Debian 13, cat si Ubuntu 24.04 il au in depozitele lor; versiunea din pachet e putin mai veche, dar perfect buna pentru un reverse proxy (Caddy are si un depozit apt propriu, daca vrei cea mai noua versiune). Inainte de instalare, verifica sa nu mai foloseasca nimic porturile 80 si 443:

sudo ss -tlnp | grep -E ':(80|443)\s' || echo "Ports 80 and 443 are free"

Daca apare Apache sau nginx, fie il opresti, fie il folosesti pe el ca proxy (vezi exemplul pentru nginx de mai jos). Apoi instaleaza Caddy si scrie-i configuratia:

sudo apt install -y caddy
sudo cp /etc/caddy/Caddyfile /etc/caddy/Caddyfile.orig
sudo tee /etc/caddy/Caddyfile > /dev/null <<'EOF'
stats.example.com {
    encode zstd gzip
    reverse_proxy 127.0.0.1:8000
}
EOF
sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo systemctl reload caddy

Facem o copie a Caddyfile-ului implicit si il inlocuim, pentru ca la o instalare noua contine doar o pagina demo. Daca folosesti deja Caddy pentru alte site-uri, nu suprascrie fisierul: adauga in el doar blocul stats.example.com { ... }. caddy validate trebuie sa se termine cu “Valid configuration”. Caddy adauga automat header-ul X-Forwarded-For, de care Plausible are nevoie ca sa vada IP-ul real al vizitatorului, pentru numararea vizitatorilor unici si detectarea tarii.

Lasa-i lui Caddy cateva secunde sa obtina certificatul, apoi testeaza de pe VPS sau de pe calculatorul tau:

curl -sI https://stats.example.com | head -n 1

O linie HTTP/2 200 sau HTTP/2 302 inseamna ca HTTPS functioneaza cap-coada. Daca primesti o eroare de certificat, citeste sudo journalctl -u caddy -n 50; aproape mereu indica o problema de DNS sau portul 80 inchis.

Folosesti deja nginx? Intr-un bloc server cu TLS si certificatul configurat, partea de proxy are nevoie de liniile de mai jos, mai ales de header-ul cu IP-ul real:

location / {
    proxy_pass http://127.0.0.1:8000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Pasul 7: Iti creezi contul si adaugi site-urile

Deschide https://stats.example.com in browser. Pentru ca nu exista inca niciun utilizator, Plausible iti arata un formular de inregistrare: completeaza numele, adresa de email si o parola puternica. Acest prim cont este proprietarul instantei. Imediat dupa logare, intra in setarile contului si activeaza autentificarea in doi pasi.

Apoi apasa Add website. Scrie domeniul exact cum il vad vizitatorii, fara https:// si fara cale, de exemplu example.com, si alege fusul orar folosit pentru statisticile zilnice. Plausible iti arata apoi fragmentul de tracking. Pentru scriptul clasic, arata asa:

<script defer data-domain="example.com" src="https://stats.example.com/js/script.js"></script>

Pune-l in sectiunea <head> a fiecarei pagini de pe site, de obicei in sablonul de header al temei sau intr-o setare de tip “header scripts” din CMS. Versiunile mai noi de Plausible pot afisa un fragment putin diferit, cu un nume de script specific site-ului, asa ca intotdeauna copiaza codul exact din Site settings > Site installation, nu il scrie din memorie. Atributul defer permite incarcarea scriptului fara sa incetineasca pagina.

Deschide site-ul intr-un alt tab si revino in dashboard-ul Plausible: in cateva secunde, contorul “current visitors” trebuie sa arate 1. Daca ramane la zero, sari la sectiunea de depanare.

Urmarirea mai multor site-uri

O singura instanta Plausible poate urmari cate site-uri duce VPS-ul tau. Repeta Add website pentru fiecare domeniu, iar fiecare site primeste propriul dashboard, propriile setari si propriul fragment, cu data-domain-ul lui. Cateva sfaturi practice:

  • example.com si www.example.com sunt acelasi site pentru Plausible, dar shop.example.com este un site separat. Adauga subdomeniile individual daca vrei dashboard-uri separate.
  • Pentru un dashboard combinat peste mai multe site-uri, scriptul clasic accepta o lista separata prin virgula: data-domain="shop.example.com,example-rollup.com" trimite fiecare afisare atat in dashboard-ul site-ului, cat si intr-un site “roll-up” pe care l-ai creat pentru totaluri.
  • Foloseste selectorul de site-uri din stanga sus a dashboard-ului ca sa treci de la un site la altul, iar din Site settings > People poti da unui coleg sau client acces doar la site-ul lui.
  • Ca sa-ti excluzi propriile vizite, deschide site-ul, deschide consola browserului si ruleaza localStorage.plausible_ignore=true. De atunci, Plausible ignora acel browser.

Obiectivele si evenimentele custom (formulare trimise, linkuri externe, descarcari de fisiere) se configureaza per site in Site settings > Goals; merita explorate dupa ce tracking-ul de baza functioneaza.

Pasul 8: Configuram SMTP pentru rapoartele pe email

Plausible trimite emailuri pentru rapoartele saptamanale si lunare, alertele de varf de trafic, invitatii si resetari de parola. Fara SMTP, niciunul nu ajunge la tine. Ia datele SMTP de la furnizorul tau de email (un serviciu de email tranzactional sau o casuta pe domeniul tau), apoi deschide fisierul .env:

cd ~/plausible-ce
nano .env

Adauga la final liniile de mai jos, cu valorile tale reale:

MAILER_EMAIL=stats@example.com
MAILER_NAME="Plausible Analytics"
SMTP_HOST_ADDR=smtp.example.com
SMTP_HOST_PORT=587
SMTP_USER_NAME=stats@example.com
SMTP_USER_PWD='parola-ta-smtp'
SMTP_HOST_SSL_ENABLED=false

MAILER_EMAIL este adresa expeditorului si trebuie sa fie una de pe care contul SMTP are voie sa trimita, ideal pe un domeniu cu SPF si DKIM configurate, altfel rapoartele ajung in spam. Portul 587 foloseste STARTTLS, care transforma conexiunea in una criptata dupa conectare, deci SMTP_HOST_SSL_ENABLED ramane false. Daca furnizorul tau foloseste portul 465 (TLS de la primul byte), pune portul 465 si SMTP_HOST_SSL_ENABLED=true. Evita portul 25, blocat de multe retele pentru emailul de iesire. Tine parola intre ghilimele simple: altfel Docker Compose ar incerca sa interpreteze un $ din ea ca variabila.

Salveaza cu Ctrl+O si Enter, iesi cu Ctrl+X, apoi aplica modificarea:

sudo docker compose up -d

Foloseste up -d, nu restart: restart refoloseste containerul existent cu mediul vechi, pe cand up -d observa ca .env s-a schimbat si recreeaza containerul Plausible. Ca sa testezi, delogheaza-te si foloseste Forgot password pe pagina de login, sau invita o a doua adresa de email la un site. Daca nu primesti nimic, cauta erori:

sudo docker compose logs --since 10m plausible | grep -iE 'smtp|mail|error'

Dupa ce emailul functioneaza, deschide Site settings > Email reports pentru fiecare site si activeaza raportul saptamanal (trimis lunea dimineata) si/sau pe cel lunar (trimis pe data de 1), adaugand toti destinatarii care trebuie sa-l primeasca. In aceeasi sectiune poti porni si notificarile pentru varfuri de trafic, care iti trimit un email cand numarul de vizitatori curenti depaseste un prag ales de tine.

Backup si actualizari

Statisticile tale stau in doua volume Docker, iar un snapshot al VPS-ului nu inlocuieste o copie pastrata in alta parte. Iata un backup manual simplu, in ~/plausible-backups:

cd ~/plausible-ce
mkdir -p "$HOME/plausible-backups"
sudo docker compose exec -T plausible_db pg_dump -U postgres plausible_db | gzip > "$HOME/plausible-backups/postgres-$(date +%F).sql.gz"
sudo docker compose stop plausible plausible_events_db
sudo docker run --rm -v plausible-ce_event-data:/data:ro -v "$HOME/plausible-backups":/backup alpine:3 tar czf "/backup/clickhouse-$(date +%F).tar.gz" -C /data .
sudo docker compose start
sudo chown "$USER": "$HOME"/plausible-backups/*
cp .env compose.override.yml "$HOME/plausible-backups/"

pg_dump ruleaza in containerul PostgreSQL si se conecteaza prin socket-ul local, deci nicio parola nu apare in linia de comanda. Pentru ClickHouse oprim scurt aplicatia si baza de evenimente, ca fisierele sa fie consistente, apoi arhivam volumul (prefixul plausible-ce_ vine din numele folderului; confirma-l cu sudo docker volume ls). Cererile de tracking care sosesc in acel minut se pierd, asa ca ruleaza backup-ul la o ora linistita. Arhiva e creata de root intr-un container, de aici chown-ul de dinainte sa copiezi folderul de pe server cu scp sau rsync. Pastreaza in siguranta si .env: fara acelasi SECRET_KEY_BASE, restaurarea nu va functiona corect.

Pentru restaurare (pe aceeasi versiune Plausible din care provine backup-ul), restaureaza mereu in volume goale, niciodata peste datele active:

cd ~/plausible-ce
sudo docker compose down
sudo docker volume rm plausible-ce_db-data plausible-ce_event-data
sudo docker compose create
sudo docker run --rm -v plausible-ce_event-data:/data -v "$HOME/plausible-backups":/backup alpine:3 tar xzf /backup/clickhouse-YYYY-MM-DD.tar.gz -C /data
sudo docker compose start plausible_db
sleep 15
sudo docker compose exec -T plausible_db createdb -U postgres plausible_db
gunzip -c "$HOME/plausible-backups/postgres-YYYY-MM-DD.sql.gz" | sudo docker compose exec -T plausible_db psql -q -U postgres -d plausible_db
sudo docker compose up -d

docker compose create recreeaza volumele goale si containerele fara sa le porneasca, deci ClickHouse nu-si atinge folderul cat timp despachetam arhiva. PostgreSQL porneste pe un volum gol, cream o baza plausible_db goala si incarcam dump-ul in ea, iar abia apoi pornim aplicatia.

Pentru actualizare, citeste mai intai notele de versiune (versiunile majore au uneori pasi de migrare in plus), fa un backup, apoi treci pe tag-ul nou:

cd ~/plausible-ce
git fetch --tags
git checkout vX.Y.Z
sudo docker compose pull
sudo docker compose up -d

Inlocuieste vX.Y.Z cu cel mai nou tag de pe pagina de release-uri. .env si compose.override.yml nu fac parte din depozit, deci raman neatinse.

Depanare si greseli frecvente

  • plausible_events_db se tot reporneste. Verifica sudo docker compose logs plausible_events_db. Un mesaj despre SSE 4.2 inseamna ca procesorul nu e suportat; o oprire brusca fara erori inseamna de obicei ca kernelul l-a omorat din lipsa de memorie (sudo dmesg | grep -i oom). Adauga swap sau treci pe un VPS cu mai mult RAM.
  • “operation not permitted” legat de ulimits sau nofile. Tipic pentru un container LXC neprivilegiat, care nu-si poate mari limita de fisiere deschise. Foloseste un VPS KVM.
  • 502 Bad Gateway de la Caddy. Plausible inca porneste (asteapta si verifica log-urile), sau porturile nu se potrivesc: HTTP_PORT din .env, partea din dreapta a maparii din compose.override.yml si adresa din Caddyfile trebuie sa foloseasca toate 8000.
  • Nu se emite certificatul. Inregistrarea DNS nu indica inca spre VPS, o inregistrare AAAA indica spre un server vechi sau portul 80 e inchis. Caddy are nevoie de portul 80 pentru verificarea Let’s Encrypt.
  • Dashboard-ul ramane gol. data-domain din fragment nu se potriveste cu domeniul adaugat, un ad blocker blocheaza scriptul (testeaza intr-o fereastra privata fara extensii), testezi de pe localhost (pe care Plausible il ignora intentionat), sau politica Content Security Policy a site-ului blocheaza stats.example.com: adauga-l si in script-src, si in connect-src.
  • Toti vizitatorii par o singura persoana sau vin din aceeasi tara. IP-ul real nu este transmis. Caddy face asta din oficiu; cu nginx sau alt proxy, seteaza X-Forwarded-For, iar daca pui un CDN in fata, asigura-te ca transmite si el IP-ul clientului.
  • Modificarile din .env nu au efect. Ai folosit docker compose restart. Ruleaza in schimb sudo docker compose up -d.
  • Linkurile din emailuri duc la adresa gresita. BASE_URL este gresit. Corecteaza-l in .env si ruleaza sudo docker compose up -d.
  • Emailurile nu ajung niciodata. Combinatie gresita de port si SSL (587 cu false, 465 cu true), o adresa de expeditor pe care furnizorul nu o accepta, sau o parola care contine $ si nu era intre ghilimele simple. Comanda de log de la pasul 8 iti arata de obicei eroarea SMTP exacta.

Note de securitate

  • Tine portul 8000 pe 127.0.0.1. Docker publica porturile inserand propriile reguli de firewall, deci ufw nu poate proteja un port de container publicat pe toate interfetele. Bazele de date nu sunt publicate deloc, si asa trebuie sa ramana.
  • Protejeaza .env. Contine SECRET_KEY_BASE si parola SMTP. Pastreaza-l cu chmod 600, in afara oricarui depozit Git public, si inclus in backup-uri.
  • Securizeaza conturile. Lasa DISABLE_REGISTRATION pe invite_only sau true, foloseste parole puternice si activeaza autentificarea in doi pasi pentru fiecare cont cu acces.
  • Gandeste-te de doua ori inainte sa faci dashboard-uri publice. Dashboard-urile sunt private implicit. Daca trebuie sa partajezi unul, prefera un link de partajare protejat cu parola in locul unui dashboard complet public.
  • Actualizeaza regulat. Urmareste versiunile Plausible CE si tine sistemul la zi cu sudo apt update && sudo apt full-upgrade. Ia in calcul unattended-upgrades pentru patch-urile de securitate automate.
  • Securizeaza SSH-ul. Foloseste autentificare cu chei, dezactiveaza logarea cu parola dupa ce cheia functioneaza si pastreaza SSH, 80 si 443 ca singurele usi deschise.
  • Nu uita partea legala. Fara cookie-uri nu inseamna “fara reguli”. Mentioneaza Plausible in politica de confidentialitate si, pentru site-urile de firma, confirma cu consultantul juridic ce se aplica in cazul tau.

Deci, merita Plausible self-hosted?

Daca vrei statistici clare si usoare pentru cateva site-uri, fara banner de cookie-uri doar pentru analytics si cu datele pe un server pe care il controlezi, Plausible CE este una dintre cele mai bune optiuni disponibile, iar instalarea de mai sus ia mult sub o ora. Compromisurile sunt cinstite: tu raspunzi de actualizari si backup-uri, iar ClickHouse vrea ceva mai mult RAM decat o aplicatie mica obisnuita. In schimb primesti site-uri si afisari nelimitate la pretul unui VPS.

Poti instala stack-ul din acest ghid pe un VPS din data center-ul nostru propriu din Romania in cateva minute, sau poti lasa echipa noastra de administrare servere sa instaleze, sa securizeze, sa faca backup si sa actualizeze Plausible pentru tine, ca tie sa-ti ramana doar deschiderea dashboard-ului.

Intrebari frecvente

Este Plausible Community Edition gratuit?

Da. Software-ul este gratuit si open source, sub AGPLv3, fara limite de site-uri sau de afisari. Platesti doar serverul pe care ruleaza. Plausible Cloud este varianta gazduita si platita de la aceeasi echipa, cu cateva functii premium in plus si fara mentenanta din partea ta.

Plausible nu seteaza cookie-uri si nu stocheaza date personale, motiv pentru care multi proprietari de site-uri il folosesc fara banner de consimtamant. Regulile difera de la o tara la alta si depind si de tot ce mai incarca site-ul tau, asa ca trateaza asta ca pe un punct de plecare solid si confirma cu consultantul juridic.

Cat trafic duce un VPS mic?

ClickHouse este foarte eficient. Orientativ, un VPS cu 2 vCPU si 4 GB RAM duce confortabil cateva site-uri cu cateva sute de mii de afisari pe luna in total; peste cateva milioane pe luna, planifica mai mult RAM si stocare mai rapida. Urmareste memoria cu docker stats pe masura ce creste traficul.

Pot importa istoricul din Google Analytics?

Da. Plausible suporta importuri din Google Analytics (necesita credentiale Google API configurate in .env), precum si importuri CSV, iar datele importate apar in dashboard alaturi de statisticile proprii.

Pot gazdui si alte site-uri pe acelasi VPS?

Da. Caddy poate servi si trimite mai departe cereri pentru mai multe domenii, cu cate un bloc pentru fiecare domeniu in Caddyfile. Doar fii atent la RAM, pentru ca ClickHouse merge cel mai bine cand are putina rezerva.

Avem Incredere & Suntem Membri

Suntem membri ai principalelor organizatii de infrastructura internet.

RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX