Luca Sacchi Ricciardi 6c8c05b13b feat: dashboard real-time con aggiornamento incrementale
- Buffer locale samples[] per aggiornamenti real-time
- Poll /api/status ogni 10 secondi
- Aggiunge nuovi campioni senza ricaricare history
- Aggiunge AGENTS.md per istruzioni agenti OpenCode
- Aggiunge team agenti in .opencode/agents/
2026-04-26 14:34:23 +02:00

Supabase Pinger

Tool Python dockerizzato pensato per mantenere "attivo" un database Supabase in free tier, evitando che venga spento e parcheggiato per inattivita'.

L'idea e' semplice: il container resta in esecuzione fino a quando non viene fermato esplicitamente e, a intervalli regolari, esegue un'operazione verso il database Supabase per generare attivita' sufficiente a non far decadere l'istanza.

In piu', il servizio espone una webapp/API con FastAPI servita da Uvicorn:

  • dashboard in stile SmokePing;
  • API read-only per stato e storico;
  • documentazione Swagger in /docs e OpenAPI in /openapi.json.

Obiettivo

I progetti Supabase in free tier possono diventare temporaneamente inaccessibili se rimangono inattivi troppo a lungo. Questo progetto serve a:

  • mantenere raggiungibile il database nel tempo;
  • centralizzare la configurazione in un file .env;
  • fornire anche un file .env.example come modello;
  • girare in un container Docker sempre attivo, finche' non viene arrestato manualmente.

Come funziona

Il servizio viene eseguito all'interno di un container Docker e resta attivo in modo continuativo. A ogni ciclo:

  1. legge la configurazione dal file .env;
  2. apre una connessione al database Supabase/PostgreSQL;
  3. esegue una query o un'operazione leggera di keep-alive;
  4. salva un campione storico (successo/errore + latenza) in uno storage locale a buffer circolare dimensionato per 48 ore;
  5. attende l'intervallo configurato;
  6. ripete il processo fino allo stop del container.

Configurazione

La configurazione deve essere persistita in un file .env, non hardcoded nel codice o nel Dockerfile.

E' consigliato mantenere nel repository anche un file .env.example con le sole chiavi, senza valori reali, per documentare le variabili richieste.

Esempio di .env.example

SUPABASE_DB_HOST=aws-1-eu-central-1.pooler.supabase.com
SUPABASE_DB_PORT=6543
SUPABASE_DB_NAME=postgres
SUPABASE_DB_USER=postgres.<project-ref>
SUPABASE_DB_PASSWORD=
PING_INTERVAL_MINUTES=4320
PING_QUERY=SELECT 1;
TZ=Europe/Rome
WEB_HOST=0.0.0.0
WEB_PORT=8080
RRD_DB_PATH=data/connection_rrd.sqlite3
RRD_RETENTION_HOURS=48

Significato delle variabili

  • SUPABASE_DB_HOST: hostname del connection pooler Supabase (consigliato per compatibilita' IPv4).
  • SUPABASE_DB_PORT: porta del pooler PostgreSQL, normalmente 6543.
  • SUPABASE_DB_NAME: nome del database.
  • SUPABASE_DB_USER: utente di connessione nel formato postgres.<project-ref> quando si usa il pooler.
  • SUPABASE_DB_PASSWORD: password di connessione.
  • PING_INTERVAL_MINUTES: intervallo tra un keep-alive e il successivo. Default 4320 (72 ore, circa 3 volte a settimana).
  • PING_QUERY: query leggera da eseguire per generare attivita'.
  • TZ: timezone del container per logging e scheduling coerenti.
  • WEB_HOST: host di bind del server Uvicorn.
  • WEB_PORT: porta HTTP della webapp/API.
  • RRD_DB_PATH: path del database storico locale (RRD-like a buffer circolare).
  • RRD_RETENTION_HOURS: retention dello storico, default 48.

API e Swagger

Endpoint principali:

  • GET /api/status: ultimo campione disponibile;
  • GET /api/history?hours=48: storico campioni (finestra max 48h);
  • GET /: dashboard web in stile SmokePing;
  • GET /docs: Swagger UI;
  • GET /openapi.json: schema OpenAPI.

Docker

Il container deve rimanere in esecuzione continua. In pratica, il processo Python non deve terminare dopo il primo ping, ma restare in loop fino a interruzione esplicita.

Build

docker build -t supabase-pinger .

Avvio con file .env

docker run -d \
  --name supabase-pinger \
  --env-file .env \
  -p 8080:8080 \
  --restart unless-stopped \
  supabase-pinger

L'opzione --restart unless-stopped e' la piu' adatta a questo caso: il container viene mantenuto attivo e riparte automaticamente dopo reboot o crash, ma si ferma se viene arrestato intenzionalmente.

Arresto

docker stop supabase-pinger

Esempio con Docker Compose

services:
  supabase-pinger:
    build: .
    container_name: supabase-pinger
    env_file:
      - .env
    ports:
      - "8080:8080"
    restart: unless-stopped

Avvio:

docker compose up -d

Stop:

docker compose down

Struttura del progetto

.
|-- .env                  # credenziali locali (non versionato)
|-- .env.example          # modello variabili senza segreti
|-- .gitignore
|-- app.py                # app FastAPI + collector keep-alive
|-- docker-compose.yml
|-- Dockerfile
|-- prd.md                # product requirements document
|-- progress.md           # piano e stato di sviluppo
|-- README.md
|-- tests/
`-- requirements.txt

Test

Esecuzione test:

pytest -q

Note operative

  • Non committare mai il file .env con credenziali reali.
  • Committa solo .env.example con valori vuoti o fittizi.
  • Usa query di keep-alive molto leggere, ad esempio SELECT 1;.
  • Mantieni intervalli ragionevoli: troppo frequenti sono inutili, troppo lunghi rischiano di non prevenire il parcheggio del database.
  • Se il progetto viene eseguito su un host sempre acceso, Docker con policy unless-stopped e' sufficiente per il requisito di esecuzione continua.

Scopo del repository

Questo repository ospita un servizio minimale e operativo, pensato per un solo compito: impedire che un database Supabase free tier diventi temporaneamente non disponibile per inattivita'.

S
Description
tool per mantenenre attivo il free tier
Readme 113 KiB
Languages
Python 98.9%
Dockerfile 1.1%