
Nel panorama degli strumenti di monitoraggio self-hosted Gatus si sta ritagliando uno spazio sempre più importante grazie alla sua filosofia semplice ma efficace: un dashboard di health check “developer-oriented”, pensato per chi vuole sapere in tempo reale se i propri servizi siti web, API, database, dispositivi di rete sono realmente raggiungibili e funzionanti, senza dover configurare uno stack di monitoring complesso.
A differenza di soluzioni basate puramente su metriche di traffico, Gatus esegue controlli attivi e programmati verso gli endpoint configurati, permettendo di intercettare un’interruzione di servizio anche quando nessun utente sta effettivamente generando richieste in quel momento.
Il tutto restituito attraverso una status page pulita, leggera e completamente personalizzabile via file YAML.
In questa guida vedremo passo passo come installare Gatus su Ubuntu Server 26.04, utilizzando Docker Compose come metodo di deployment: partiremo dall’installazione di Docker Engine da zero, per poi arrivare a una configurazione base funzionante, con endpoint di esempio, storage persistente su SQLite e alcune indicazioni per l’esposizione sicura tramite reverse proxy.
Un punto di partenza solido per chi vuole integrare un sistema di status monitoring leggero nel proprio homelab o nella propria infrastruttura di produzione.
PREREQUISITI
- Un server Ubuntu 26.04 con accesso sudo
- Docker Engine (versione 19.03 o superiore, API 1.40+) e il plugin Docker Compose
- Un container già in esecuzione, giusto per avere qualche log da guardare
AGGIORNAMENTO DEL SISTEMA
Aggiornare il sistema con i seguenti comandi:
|
0
1
2
|
sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg
|
INSTALLAZIONE DI DOCKER ENGINE + DOCKER COMPOSE PLUGIN
Creare la directory per le chiavi GPG con il comando:
|
0 |
sudo install -m 0755 -d /etc/apt/keyrings
|
Aggiungere la chiave GPG ufficiale di Docker con i comandi:
|
0
1
2
|
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
|
Aggiungere il repository Docker con il comando:
|
0
1
2
3
|
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
Aggiornare e installare Docker + Compose plugin con i comandi:
|
0
1
2
|
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
NOTA BENE: Ubuntu 26.04 è recentissima se il repository Docker non ha ancora una entry specifica per il suo codename, il comando sopra userà comunque il nome codename rilevato da os-release. Se apt update desse errore per il repo, verifica su https://download.docker.com/linux/ubuntu/dists/ quale codename è disponibile e sostituiscilo manualmente.
VERIFICARE L’INSTALLAZIONE DI DOCKER
Verificare l’installazione di Docker con i seguenti comandi:
|
0
1
2
3
4
|
sudo docker --version
sudo docker compose version
sudo systemctl status docker
|
Dovremmo visualizzare 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
|
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-07-12 19:56:12 UTC; 1min 18s ago
Invocation: cc37e30724f641f694ef48dfdbb5fec7
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 30242 (dockerd)
Tasks: 10
Memory: 27.8M (peak: 28.1M)
CPU: 316ms
CGroup: /system.slice/docker.service
└─30242 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Jul 12 19:56:12 vm-srv-test dockerd[30242]: time="2026-07-12T19:56:12.022827820Z" level=info msg="Restoring containers: start."
Jul 12 19:56:12 vm-srv-test dockerd[30242]: time="2026-07-12T19:56:12.051534074Z" level=info msg="Deleting nftables IPv4 rules" error="running nft: /dev/stdin:1:17-30: >
Jul 12 19:56:12 vm-srv-test dockerd[30242]: time="2026-07-12T19:56:12.058935552Z" level=info msg="Deleting nftables IPv6 rules" error="running nft: /dev/stdin:1:18-31: >
Jul 12 19:56:12 vm-srv-test dockerd[30242]: time="2026-07-12T19:56:12.275806869Z" level=info msg="Loading containers: done."
Jul 12 19:56:12 vm-srv-test dockerd[30242]: time="2026-07-12T19:56:12.283474191Z" level=info msg="Docker daemon" commit=8ec5ab3 containerd-snapshotter=true storage-driv>
Jul 12 19:56:12 vm-srv-test dockerd[30242]: time="2026-07-12T19:56:12.283562293Z" level=info msg="Initializing buildkit"
Jul 12 19:56:12 vm-srv-test dockerd[30242]: time="2026-07-12T19:56:12.384444825Z" level=info msg="Completed buildkit initialization"
Jul 12 19:56:12 vm-srv-test dockerd[30242]: time="2026-07-12T19:56:12.390776109Z" level=info msg="Daemon has completed initialization"
Jul 12 19:56:12 vm-srv-test dockerd[30242]: time="2026-07-12T19:56:12.390817886Z" level=info msg="API listen on /run/docker.sock"
Jul 12 19:56:12 vm-srv-test systemd[1]: Started docker.service - Docker Application Container Engine.
|
UTILIZZO DI DOCKER SENZA SUDO (OPZIONALE MA CONSIGLIATO)
Per utilizzare Docker senza sudo eseguire i comandi di seguito:
|
0
1
2
|
sudo usermod -aG docker $USER
newgrp docker
|
Poi verificare con il seguente comando:
|
0 |
docker run hello-world
|
CREAZIONE DELLA STRUTTURA DI CARTELLE PER GATUS
Creare la struttura delle cartelle per Gatus con i seguenti comandi:
|
0
1
2
|
mkdir -p ~/gatus/config ~/gatus/data
cd ~/gatus
|
CREAZIONE DEL FILE DOCKER-COMPOSE.YML
Creare il file docker-compose.yml con il comando:
|
0 |
sudo nano docker-compose.yml
|
Quindi incollare all’interno il seguente output:
|
0
1
2
3
4
5
6
7
8
9
10
11
|
services:
gatus:
image: ghcr.io/twin/gatus:stable
container_name: gatus
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./config/config.yaml:/config/config.yaml:ro
- ./data:/data
environment:
- GATUS_CONFIG_PATH=/config/config.yaml
|
Salvare e chiudere il file di configurazione.
CREAZIONE DEL FILE DI CONFIGURAZIONE CONFIG/CONFIG.YAML
Creare il file di configurazione config/config.yaml con il comando:
|
0 |
sudo nano config/config.yaml
|
Quindi incollare all’interno il seguente output:
|
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
storage:
type: sqlite
path: /data/data.db
web:
port: 8080
endpoints:
- name: Google
url: "https://google.com"
interval: 60s
conditions:
- "[STATUS] == 200"
- "[RESPONSE_TIME] < 1000"
- name: Sito di esempio
url: "https://tuo-dominio-esempio.it"
interval: 60s
conditions:
- "[STATUS] == 200"
|
Salvare e chiudere il file di configurazione.
Sostituire gli endpoint con i servizi reali da monitorare (siti, API, ESXi, vCenter, Portainer, ecc.).
AVVIO DEL CONTAINER
Avviare il Docker con il comando:
|
0 |
docker compose up -d
|
Dovremmo visualizzare il seguente output:
|
0
1
2
3
|
[+] up 7/7
✔ Image ghcr.io/twin/gatus:stable Pulled 4.1s
✔ Network gatus_default Created 0.0s
✔ Container gatus Started
|
Verificare i log con il comando:
|
0 |
docker compose logs -f gatus
|
Dovremmo visualizzare il seguente output:
|
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
gatus | 2026/07/12 20:03:50 [main.configureLogging] Log Level is set to INFO
gatus | 2026/07/12 20:03:50 [config.LoadConfiguration] Reading configuration from configFile=/config/config.yaml
gatus | 2026/07/12 20:03:50 [config.ValidateAlertingConfig] Alerting is not configured
gatus | 2026/07/12 20:03:50 [config.ValidateEndpointsConfig] Validated 2 endpoints
gatus | 2026/07/12 20:03:50 [config.ValidateEndpointsConfig] Validated 0 external endpoints
gatus | 2026/07/12 20:03:50 [config.ValidateSuitesConfig] No suites configured
gatus | 2026/07/12 20:03:50 [main.initializeStorage] Total endpoint keys to preserve: 2
gatus | 2026/07/12 20:03:50 [controller.Handle] Listening on 0.0.0.0:8080
gatus |
gatus | ┌───────────────────────────────────────────────────┐
gatus | │ Fiber v2.52.13 │
gatus | │ http://[::]:8080 │
gatus | │ │
gatus | │ Handlers ............ 41 Processes ........... 1 │
gatus | │ Prefork ....... Disabled PID ................. 1 │
gatus | └───────────────────────────────────────────────────┘
gatus |
gatus | 2026/07/12 20:03:51 [watchdog.executeEndpoint] Monitored group=; endpoint=Google; key=_google; success=true; errors=0; duration=194ms
gatus | 2026/07/12 20:03:51 [api.ErrorHandler] Cannot GET /api/events/stream
gatus | 2026/07/12 20:03:52 [watchdog.executeEndpoint] Monitored group=; endpoint=Sito di esempio; key=_sito-di-esempio; success=true; errors=0; duration=1.07s
|
ACCESSO ALLA DASHBOARD DI GATUS
Per accedere alla Dashboard di Gatus da un qualsiasi browser richiamare il link:
http://<IP-del-server>:8080
Dovremmo visualizzare la Dashboard di Gatus con i due Host monitorati
ABILITARE L’AUTENTICAZIONE BASE (OPZIONALE)
Per abilitare l’autenticazione su Gatus eseguire il comando:
|
0
1
|
sudo apt install -y apache2-utils
htpasswd -bnBC 10 '' TuaPasswordSicura | tr -d ':\n' | base64
|
Nel file config.yaml aggiungere le seguenti righe:
|
0
1
2
3
|
security:
basic:
username: admin
password-bcrypt-base64: "INCOLLA_QUI_L'HASH"
|
Salvare e chiudere il file di configurazione
Riavviare Docker con il comando:
|
0 |
docker compose up -d
|
Fare un refresh della pagina web e se è tutto corretto dovrebbe chiedere la credenziali di accesso.
ABILITARE L’ALERT VIA EMAIL (OPZIONALE)
Per abilitare gli alert via mail inserire all’interno del file config.yaml le seguenti righe:
|
0
1
2
3
4
5
6
7
8
|
alerting:
email:
from: "[email protected]"
to: "[email protected]"
smtp:
host: smtp.example.com
port: 587
username: user
password: pass
|
Salvare e chiudere il file di configurazione.
MANUTENZIONE
Per aggiornare Gatus alla nuova versione eseguire i comandi:
|
0
1
2
3
4
|
cd ~/gatus
docker compose pull
docker compose up -d
|
Per controllare la dimensione del database SQLite eseguire il comando:
|
0 |
du -sh ~/gatus/data/
|
FUNZIONALITA’ DI GATUS CON PRO E CONTRO
Ecco l’elenco completo delle funzionalità di Gatus, con pro e contro per ciascuna area.
Tipi di health check
Funzionalità: monitoraggio via HTTP, TCP, ICMP (ping), DNS, STARTTLS/TLS, e persino query GraphQL Gatus è una dashboard di health monitoring orientata agli sviluppatori che permette di monitorare i servizi tramite query HTTP, ICMP, TCP e DNS. TwiN
✅ Pro: copre praticamente ogni tipo di servizio (web app, database, DNS interni, certificati, dispositivi di rete raggiungibili solo via ping).
✅ Pro: supporta anche richieste GraphQL con verifica del body, utile per API moderne.
⚠️ Contro: nessun check “agent-based” (a differenza di Zabbix/Prometheus node_exporter) non misura CPU/RAM/disco dell’host, solo raggiungibilità/risposta del servizio.
Condizioni di valutazione (conditions)
Funzionalità: condizioni flessibili su status code, tempo di risposta, contenuto del body (JSON path), scadenza certificati, IP Gatus valuta il risultato delle query usando una lista di condizioni su valori come il codice di stato, il tempo di risposta, la scadenza del certificato e il body. TwiN
✅ Pro: molto più granulare di un semplice “è su/giù” puoi verificare che l’API risponda con dati corretti, non solo con HTTP 200.
✅ Pro: utilizzabile anche come test di accettazione automatizzati (UAT), non solo monitoring.
⚠️ Contro: la sintassi delle condizioni (JSON path custom, placeholder [STATUS], [BODY], ecc.) richiede una curva di apprendimento iniziale, specialmente per condizioni complesse su body annidati.
⚠️ Contro: l’operatore pat() (pattern matching) è molto più oneroso computazionalmente di un confronto diretto, quindi va usato con parsimonia.
Alerting multi-canale
Funzionalità: integrazioni native con Slack, Discord, Teams, PagerDuty, Twilio, Telegram, Email, Mattermost, Google Chat, Opsgenie, Gotify, ntfy, HomeAssistant, GitHub, GitLab, iLert e provider custom via webhook.
✅ Pro: copertura estremamente ampia “out of the box”, incluse integrazioni home-lab friendly come ntfy e HomeAssistant.
✅ Pro: soglie configurabili per failure/success (es. avvisa solo dopo 3 fallimenti consecutivi, chiudi l’alert dopo 2 successi).
✅ Pro: provider custom per casi non coperti (es. rollback automatici, webhook interni).
⚠️ Contro: ogni provider ha una sintassi di configurazione leggermente diversa nello YAML, quindi bisogna consultare la doc per ciascuno.
⚠️ Contro: non tutti i provider gestiscono l’auto-risoluzione (send-on-resolved) allo stesso modo per alcuni (es. PagerDuty, iLert) è fortemente raccomandato abilitarla per evitare incident “fantasma” aperti.
Storage dei dati storici
Funzionalità: storage in memoria, SQLite (default consigliato) o PostgreSQL Gatus supporta anche uno storage PostgreSQL configurabile tramite stringa di connessione. Libre Self-hosted
✅ Pro: SQLite è zero-config e perfetto per homelab/singola istanza.
✅ Pro: PostgreSQL disponibile per scenari multi-istanza o retention più lunga.
⚠️ Contro: lo storage in memoria (default se non configurato) perde tutto lo storico ad ogni riavvio del container.
⚠️ Contro: nessun supporto nativo per storage a lungo termine tipo time-series DB (InfluxDB/Prometheus) se ti servono dashboard analitiche avanzate, va integrato esternamente.
Dashboard e status page
Funzionalità: dashboard web con dark mode, badge di stato (anche integrabili in README GitHub), raggruppamento endpoint per categoria.
✅ Pro: interfaccia pulita, leggera, pensata per essere pubblica (status page stile StatusPage.io).
✅ Pro: badge integrabili ovunque (utile per un post sul blog o repo Gitea).
⚠️ Contro: la personalizzazione grafica è limitata rispetto a soluzioni più “enterprise” (Uptime Kuma ha temi più ricchi, Kener è pensato apposta per status page brandizzate).
Sicurezza e accesso
Funzionalità: autenticazione basic (bcrypt), OIDC (in alpha).
✅ Pro: protezione semplice via basic auth per dashboard esposte pubblicamente.
⚠️ Contro: OIDC è ancora in stato alpha — non affidarti ad esso per ambienti di produzione critici, specialmente se hai già SSO aziendale da integrare stabilmente.
⚠️ Contro: nessun sistema di ruoli/permessi granulare (RBAC) è tutto o niente sull’accesso alla dashboard.
Metriche e osservabilità
Funzionalità: endpoint /metrics in formato Prometheus.
✅ Pro: si integra facilmente col tuo stack Grafana/Prometheus esistente.
✅ Pro: basso consumo di risorse, tipico delle applicazioni Go il consumo di risorse richiesto è trascurabile, come tipico delle applicazioni Go.
Deployment e automazione
Funzionalità: Docker, Helm Chart per Kubernetes, Terraform provider, auto-discovery Kubernetes (alpha), istanze remote (sperimentale).
✅ Pro: ottimo fit sia per homelab Docker/Portainer sia per cluster K8s più strutturati.
✅ Pro: configurazione dichiarativa in YAML → si presta benissimo a GitOps (perfetto per il tuo workflow con Gitea).
⚠️ Contro: auto-discovery K8s e istanze remote sono ancora sperimentali/alpha non stabili al 100% per produzione.
Filosofia generale: monitoraggio “esterno” vs metriche interne
Funzionalità: check attivi e sintetici, non dipendenti dal traffico reale a differenza delle metriche che dipendono dal traffico esistente, Gatus ti avvisa anche se nessun cliente sta attivamente chiamando l’endpoint in quel momento. Openaitx
✅ Pro: rileva problemi anche prima che gli utenti reali li notino (es. load balancer giù senza traffico).
⚠️ Contro: essendo check sintetici a intervalli, non sostituisce un vero APM (Application Performance Monitoring) per diagnosticare cause profonde di degradazione è complementare, non alternativo, a strumenti come Prometheus/Grafana per metriche interne.

0 commenti