
Chi gestisce un sito web prima o poi deve chiedersi quanti utenti lo visitano, da dove arrivano e quali contenuti funzionano meglio.
Per anni la risposta quasi automatica è stata Google Analytics. Oggi però la scelta non è più così scontata, tra l’attenzione crescente alla privacy, il GDPR, i banner dei cookie sempre più invasivi e il desiderio di tenere i propri dati sotto controllo.
Umami è una piattaforma di web analytics open source, leggera e pensata per rispettare la privacy dei visitatori.
Non usa cookie, non raccoglie dati personali e non traccia gli utenti tra siti diversi.
Offre comunque tutte le metriche che servono davvero: visualizzazioni di pagina, visitatori unici, sorgenti di traffico, dispositivi, browser, paesi di provenienza ed eventi personalizzati.
Il tutto in una dashboard pulita e immediata, lontana dalla complessità di strumenti più blasonati.
Il punto di forza principale è che Umami si può installare in self-hosting sulla propria infrastruttura.
Così i dati delle statistiche restano sul nostro server e non passano da servizi di terze parti.
In questa guida vedremo passo passo come installare e configurare Umami su Ubuntu Server 26.04 usando Docker Compose.
Con questo approccio il deploy è rapido, gli aggiornamenti sono semplici e l’ambiente resta ordinato e portabile. Partiremo dalla preparazione del server e arriveremo al primo accesso alla dashboard. Lungo la strada configureremo il database PostgreSQL e collegheremo il primo sito da monitorare.
PREREQUISITI
Un server con Ubuntu Server 26.04 LTS già installato, con accesso SSH e un utente con permessi sudo.
Risorse minime: Umami è leggero 1 vCPU e 1 GB di RAM sono sufficienti per un sito con traffico moderato; per più siti o volumi alti, meglio 2 GB+.
L’indirizzo IP del server, che userai per raggiungere Umami dal browser (es. 192.0.2.10).
Connessione internet in uscita sul server, per scaricare pacchetti e immagini Docker.
PREPARAZIONE DEL SERVER
Collegati via SSH e porta il sistema all’ultima versione dei pacchetti.
|
0
1
|
sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg openssl
|
Verifica che il fuso orario del sistema sia impostato su UTC: Umami e PostgreSQL si comportano meglio così, ed è più semplice confrontare i dati con altri strumenti.
|
0
1
2
|
sudo timedatectl set-timezone UTC
timedatectl
|
Dovremmo visualizzare un output simile al seguente:
|
0
1
2
3
4
5
6
|
Local time: Sat 2026-10-10 19:24:31 UTC
Universal time: Sat 2026-10-10 19:24:31 UTC
RTC time: Sat 2026-10-10 19:24:31
Time zone: UTC (UTC, +0000)
System clock synchronized: no
NTP service: active
RTC in local TZ: no
|
INSTALLAZIONE DI DOCKER ENGINE
Aggiungi il repository ufficiale Docker e installa Engine, CLI e il plugin compose. Ubuntu 26.04 (“Resolute”) è tra le versioni supportate ufficialmente da Docker.
|
0
1
2
3
4
5
6
7
8
9
10
11
|
# Chiave GPG e repository apt di Docker
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/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/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
|
Quindi aggiornare con il comando:
|
0 |
sudo apt update
|
Quindi procedere con l’installazione:
|
0 |
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
Verifica che l’installazione funzioni con i comandi:
|
0
1
2
|
sudo systemctl status docker --no-pager
sudo docker run --rm hello-world
docker compose version
|
OPZIONALE: usare Docker senza sudo
Per lanciare i comandi Docker senza anteporre sudo, aggiungi il tuo utente al gruppo docker e apri una nuova sessione SSH.
|
0
1
|
sudo usermod -aG docker $USER
newgrp docker
|
Dovremmo visualizzare un output simile al seguente:
|
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
Docker Compose version v5.6.0
|
CREAZIONE DELLA CARTELLA DI PROGETTO
Tieni Umami in una cartella dedicata: rende più semplici backup e aggiornamenti.
|
0
1
2
|
sudo mkdir -p /opt/umami
sudo chown $USER:$USER /opt/umami
cd /opt/umami
|
Genera due segreti che useremo nel prossimo passaggio: la password del database e la chiave APP_SECRET di Umami (usata per firmare le sessioni — deve restare privata).
|
0
1
|
openssl rand -hex 24 # → usa il risultato come password del DB
openssl rand -hex 32 # → usa il risultato come APP_SECRET
|
Crea un file .env con i valori generati (sostituisci i segnaposto):
|
0 |
sudo nano .env
|
Inserire all’interno del file il seguente output:
|
0
1
2
3
|
POSTGRES_DB=umami
POSTGRES_USER=umami
POSTGRES_PASSWORD=sostituisci-con-il-primo-valore-generato
APP_SECRET=sostituisci-con-il-secondo-valore-generato
|
ATTENZIONE: Non usare le password d’esempio delle guide online (umami/umami): sono note pubblicamente e il servizio finirebbe esposto sull’IP del server.
SCRIVERE IL DOCKER-COMPOSE.YML
Nella stessa cartella, crea docker-compose.yml con i due servizi: il database PostgreSQL e l’applicazione Umami, entrambi con healthcheck così Umami parte solo quando il database è davvero pronto.
|
0 |
sudo nano docker-compose.yml
|
Inserire all’interno del file YML il seguente output:
|
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
services:
umami:
image: docker.umami.is/umami-software/umami:postgresql-latest
container_name: umami
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
DATABASE_TYPE: postgresql
APP_SECRET: ${APP_SECRET}
depends_on:
db:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "curl -fSs http://localhost:3000/api/heartbeat || exit 1"]
interval: 10s
timeout: 5s
retries: 5
db:
image: postgres:15-alpine
container_name: umami-db
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- umami-db-data:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
umami-db-data:
|
NOTA BENE: Docker Compose legge automaticamente il file .env nella stessa cartella e sostituisce le variabili ${…}: non serve altro collegamento tra i due file.
VARIABILI UTILIZZATE
Di seguito l’utilizzo delle variabili:
POSTGRES_DB/USER/PASSWORD – .env – Credenziali del database, condivise tra i due servizi
DATABASE_URL – compose – Stringa di connessione che Umami usa verso il container db
APP_SECRET – .env – Chiave usata da Umami per firmare le sessioni utente
AVVIO DI UMAMI
Dalla cartella /opt/umami, scarica le immagini e avvia i container in background.
|
0 |
docker compose up -d
|
Dovremmo visualizzare il seguente output:
|
0
1
2
3
4
5
6
|
[+] up 40/40
✔ Image postgres:15-alpine Pulled 9.5s
✔ Image docker.umami.is/umami-software/umami:postgresql-latest Pulled 23.8s
✔ Network umami_default Created 0.1s
✔ Volume umami_umami-db-data Created 0.0s
✔ Container umami-db Healthy 12.4s
✔ Container umami Started
|
Al primo avvio Umami esegue automaticamente le migrazioni del database: può richiedere qualche istante. Controlla lo stato e i log:
|
0
1
2
|
docker compose ps
docker compose logs -f umami # Ctrl+C per uscire dai log
|
Quando entrambi i servizi mostrano stato healthy, Umami è pronto sulla porta 3000 del server.
APERTURA DELLE PORTE NEL FIREWALL
Se ufw non è ancora attivo, configuralo lasciando sempre passare SSH prima di abilitarlo, per non restare tagliati fuori dal server.
|
0
1
2
3
|
sudo ufw allow OpenSSH
sudo ufw allow 3000/tcp
sudo ufw enable
sudo ufw status
|
Senza un reverse proxy, il traffico verso la porta 3000 non è cifrato (HTTP semplice) e la porta è raggiungibile da chiunque conosca l’IP. Se il server ha un IP fisso e conosci in anticipo da dove ti collegherai, restringi l’accesso con sudo ufw allow from <TUO-IP> to any port 3000 al posto della regola generica.
ACCESSO TRAMITE WEB GUI
Apri nel browser http://<IP-DEL-SERVER>:3000 e accedi con le credenziali predefinite
Inserire le seguenti credenziali:
utente: admin
password: umami
ATTENZIONE: Cambia la password subito dopo il primo accesso, da Impostazioni → Profilo. Le credenziali predefinite sono pubbliche e note a chiunque abbia letto la documentazione di Umami.
Se è andato tutto a buon fine dovremmo visualizzare la Dashboard di Umami
CONFIGURAZIONE DI BASE
Aggiungere il primo sito
Vai su Impostazioni → Websites → Add website
Inserire la descrizione del sito e il dominio quindi cliccare Save
Dovremmo visualizzare il sito come mostrato nell’immagine sobvrastante
Umami genera uno snippet <script> univoco per quel sito.
Incolla lo snippet prima della chiusura del tag </head> di ogni pagina del sito da monitorare.
Regolare fuso orario e formato dati
In Impostazioni → Profilo puoi impostare il tuo fuso orario di visualizzazione (il database resta in UTC) e la lingua dell’interfaccia.
Dalla Dashboard di Umami sarà possibile visualizzare tutte le info relative al sito
CREAZIONE DI UTENTI AGGIUNTIVI
Se altre persone del team devono consultare le statistiche, creale da Impostazioni → Utenti invece di condividere l’account admin.
MANUTENZIONE
Aggiornare Umami con i seguenti comandi:
|
0
1
2
|
cd /opt/umami
docker compose pull
docker compose up -d
|
Backup del database con i seguenti comandi:
|
0 |
docker exec umami-db pg_dump -U umami umami > backup-umami-$(date +%F).sql
|
Comandi utili
|
0
1
2
3
4
5
6
|
docker compose stop # ferma i container, mantiene i dati
docker compose start # riavvia dopo uno stop
docker compose down # rimuove i container, il volume dati resta
docker compose logs -f # segue i log di entrambi i servizi
|
CONSIDERAZIONI FINALI
Con pochi comandi e un file docker-compose.yml abbiamo messo in piedi una piattaforma di web analytics completa e indipendente, che gira interamente sulla nostra infrastruttura. È proprio questo il valore principale di Umami: raccoglie le statistiche che contano senza sacrificare la privacy dei visitatori e senza consegnare i dati a servizi esterni.
Dopo averlo provato sul campo, ecco i punti di forza che mi hanno convinto:
Privacy by design: niente cookie e niente dati personali. Nella maggior parte dei casi questo semplifica parecchio la conformità al GDPR e può evitare il classico banner dei cookie per le sole statistiche.
Leggerezza: lo script di tracking pesa pochi kilobyte e non rallenta il sito, un dettaglio da non sottovalutare anche in ottica SEO e Core Web Vitals.
Semplicità: la dashboard è chiara e immediata e le informazioni utili si trovano in pochi secondi, senza perdersi tra menu e report.
Multi-sito e multi-utente: da un’unica istanza si possono monitorare più siti e dare accesso a colleghi o clienti, anche con dashboard condivise in sola lettura.
Open source e self-hosted: il controllo completo resta nostro, senza costi di licenza né vincoli con un fornitore.
Ci sono però anche alcuni limiti da tenere a mente:
Chi arriva da Google Analytics non troverà funzionalità avanzate come funnel complessi, attribuzione multicanale o integrazione nativa con le piattaforme pubblicitarie.
Il self-hosting richiede un minimo di manutenzione: aggiornamenti dei container, backup del database PostgreSQL e monitoraggio del server sono a nostro carico.
Come tutti gli strumenti di analytics, Umami può essere bloccato dagli ad-blocker più aggressivi. Si può attenuare il problema rinominando lo script di tracking o servendolo tramite reverse proxy sul proprio dominio.
In conclusione, Umami è un’ottima scelta per blog, siti aziendali, portali di documentazione e progetti personali.
È adatta a chiunque voglia statistiche affidabili e rispettose della privacy senza la complessità di Google Analytics.
Per chi già gestisce un’infrastruttura Docker, il costo di adozione è praticamente nullo e i vantaggi si vedono da subito.

0 Commenti