Installazione
L'hub è un container Docker con una cartella per i suoi dati. Gli agent sono facoltativi, vedi Località.
──Avviare l'hub
docker run -d --name pingtxt --restart unless-stopped \-p 8090:8090 -v ./data:/data \ghcr.io/federico-it/pingtxt:latest
Oppure docker compose up -d con il docker-compose.yml del repository. Apri
http://localhost:8090, crea l'account admin e aggiungi il primo monitor.
L'immagine gira su linux/amd64 e linux/arm64. Tag Docker: :latest è la release più recente, :1.2.3 una release
precisa, :main l'ultima build del branch main. I binari dell'hub per Linux (e degli agent per Linux e macOS) sono
nella pagina delle release, vedi senza Docker.
──Configurazione
Tutto si configura dall'interfaccia web in impostazioni e viene salvato nel database: URL pubblico, località integrata, conservazione dello storico, valori predefiniti dei nuovi monitor, utenti e accesso. All'avvio vengono lette solo poche variabili d'ambiente:
| env | predefinito | |
|---|---|---|
PINGTXT_ADDR |
:8090 |
indirizzo di ascolto (IPv4 e IPv6) |
PINGTXT_DATA |
/data |
cartella del database SQLite, dei backup e dei ripristini in attesa |
PINGTXT_DB_URL |
PostgreSQL o MariaDB/MySQL al posto di SQLite, vedi sotto | |
PINGTXT_DISABLE_UPDATE_CHECK |
true: non chiede mai a GitHub le nuove release, vedi amministrazione |
|
PINGTXT_DISABLE_TELEMETRY |
true: non invia mai statistiche d'uso e nasconde la domanda, vedi amministrazione |
|
PINGTXT_IPV6 |
on o off salta la verifica della raggiungibilità IPv6, vedi IPv6 |
|
PINGTXT_UNPRIVILEGED_PING |
1 o 0 forza il socket ICMP senza privilegi o quello raw, vedi senza Docker |
|
PINGTXT_AGENT_DIR |
cartella dei binari degli agent, quando non sono accanto all'hub |
PINGTXT_PUBLIC_URL, PINGTXT_RETENTION_DAYS, PINGTXT_LOCAL_NAME e PINGTXT_DISABLE_LOCAL funzionano ancora, ma
compilano le impostazioni solo al primo avvio. Dopo, si cambiano dall'interfaccia.
Imposta l'URL pubblico in impostazioni → generali appena l'hub ha il suo indirizzo definitivo: lo usano i link nelle email, i callback di accesso, gli URL heartbeat e i comandi di installazione degli agent.
──Container senza root
Le immagini dell'hub e degli agent eseguono pingtxt con l'utente pingtxt (uid/gid 10001), non come root. Il
container parte come root solo per l'entrypoint, che:
- assegna
/dataapingtxtquando alcuni file appartengono a un altro utente (i volumi delle versioni precedenti erano scritti da root: il primo avvio dopo l'aggiornamento li sistema); - aggiunge
pingtxtal gruppo di un socket Docker montato (per i monitor container docker); - passa a
pingtxtsenza capability tranneCAP_NET_RAW(per il ping), conno-new-privileges.
Per saltare il passaggio come root, imposta tu l'utente (--user 10001:10001, oppure user: "10001:10001" nel
compose). La cartella dei dati deve allora appartenere a quell'utente (sudo chown -R 10001:10001 ./data), e un
socket Docker richiede group_add: ["<gid di /var/run/docker.sock>"]. Se l'entrypoint non riesce a cambiare il
proprietario di /data (per esempio una condivisione NFS), scrive un avviso nel log e gira come root.
Esegui le opzioni da riga di comando con lo stesso utente: docker exec -u pingtxt pingtxt pingtxt -backup ....
──PostgreSQL o MariaDB
SQLite è il predefinito e non richiede altro. Per tenere i dati in PostgreSQL 13+ o MariaDB 10.6+ / MySQL
8.0.13+, imposta PINGTXT_DB_URL. Il database deve esistere ed essere vuoto (o contenere uno schema di pingtxt);
le tabelle vengono create e migrate all'avvio.
PINGTXT_DB_URL=postgres://pingtxt:secret@db:5432/pingtxt?sslmode=disablePINGTXT_DB_URL=mariadb://pingtxt:secret@db:3306/pingtxt # va bene anche mysql://...
I caratteri speciali nella password vanno codificati per URL. I file compose pronti avviano hub e database con un solo comando:
curl -O https://raw.githubusercontent.com/federico-it/pingtxt/main/docker-compose.postgres.ymlecho "DB_PASSWORD=$(openssl rand -hex 16)" > .envdocker compose -f docker-compose.postgres.yml up -d
curl -O https://raw.githubusercontent.com/federico-it/pingtxt/main/docker-compose.mariadb.ymlprintf "DB_PASSWORD=%s\nDB_ROOT_PASSWORD=%s\n" $(openssl rand -hex 16) $(openssl rand -hex 16) > .envdocker compose -f docker-compose.mariadb.yml up -d
I file compose non partono senza le password in .env. Il container del database le usa solo quando crea il
database la prima volta, quindi impostale prima del primo avvio.
Tutto funziona allo stesso modo sui tre database, tranne i backup del database integrati, che sono file SQLite: con PostgreSQL o MariaDB fai il backup del server con i suoi strumenti (comandi). Per spostare un hub SQLite esistente, esporta la configurazione con i segreti e importala nel nuovo hub; lo storico non viene spostato.
──Reverse proxy
Metti l'hub dietro un reverse proxy con TLS (Caddy, Traefik, nginx) e imposta l'URL pubblico in
impostazioni → generali. L'upgrade WebSocket deve essere permesso su /api/agent/ws, dove si collegano gli
agent.
status.example.com {reverse_proxy 127.0.0.1:8090}
Caddy inoltra i WebSocket senza impostazioni in più. Le status page su un dominio personalizzato passano dallo stesso hub.
──Coolify
Il repository ha due file compose pronti per Coolify: docker-compose.coolify.yml (SQLite) e docker-compose.coolify.postgres.yml (PostgreSQL). In Coolify crea una nuova risorsa di tipo Docker Compose Empty, incolla uno dei due file e fai il deploy.
Coolify riempie da solo le variabili: SERVICE_URL_PINGTXT_8090 crea il dominio e lo inoltra alla porta 8090
con TLS, e utente e password di PostgreSQL arrivano da SERVICE_USER_POSTGRES e SERVICE_PASSWORD_POSTGRES.
Non c'è niente da scrivere a mano. Per usare un tuo dominio cambialo nelle impostazioni del servizio prima del
primo deploy: l'URL pubblico viene preso da lì solo al primo avvio, poi si cambia in impostazioni → generali.
I dati restano nel volume pingtxt-data (e pingtxt-postgres per il database). La rete Docker di Coolify non ha
IPv6 di default, quindi i controlli verso destinazioni solo IPv6 falliscono dall'hub; falli partire da un
agent con IPv6.
──IPv6
L'hub ascolta su IPv4 e IPv6, e ogni tipo di controllo funziona su IPv6 (vedi IPv6 nei monitor). Docker non dà IPv6 ai container sulla rete predefinita, quindi i controlli verso destinazioni IPv6 falliscono dal container anche se il server ha IPv6. Attivalo sulla rete (Docker 27 o successivo):
# docker-compose.ymlnetworks:default:enable_ipv6: true
Con docker run, crea una rete con docker network create --ipv6 pingtxt e aggiungi --network pingtxt, oppure usa
--network host. Le porte pubblicate accettano client IPv6 in ogni caso.
L'hub e ogni agent verificano se raggiungono Internet via IPv6 all'avvio e ogni 10 minuti. Imposta
PINGTXT_IPV6=on o off per saltare la verifica nelle reti che bloccano gli indirizzi che usa.
──Senza Docker
Scarica l'hub (pingtxt-linux-amd64 o pingtxt-linux-arm64) e i binari pingtxt-agent-* dalla
pagina delle release, oppure
compilali. L'hub cerca i dati in ./data e i binari degli agent in
./dist/agents; imposta PINGTXT_DATA e PINGTXT_AGENT_DIR per metterli altrove.
I controlli ping usano un socket raw quando il processo ha CAP_NET_RAW, altrimenti un socket ICMP senza
privilegi, che richiede il gruppo del processo in net.ipv4.ping_group_range (la maggior parte delle distribuzioni
con systemd lo permette). Dai la capability al binario con sudo setcap cap_net_raw+ep /usr/local/bin/pingtxt,
oppure AmbientCapabilities=CAP_NET_RAW nella unit. PINGTXT_UNPRIVILEGED_PING=1 usa sempre il socket senza
privilegi, 0 sempre quello raw.
Una unit systemd minima:
# /etc/systemd/system/pingtxt.service[Unit]Description=pingtxt hubAfter=network-online.targetWants=network-online.target[Service]ExecStart=/usr/local/bin/pingtxtEnvironment=PINGTXT_DATA=/var/lib/pingtxt PINGTXT_AGENT_DIR=/usr/local/share/pingtxt/agentsStateDirectory=pingtxtDynamicUser=yesAmbientCapabilities=CAP_NET_RAWRestart=on-failure[Install]WantedBy=multi-user.target
Gli agent si aggiornano alla versione dell'hub, quindi tieni in PINGTXT_AGENT_DIR i binari degli agent della
stessa release.