Obelica Docs
Roadmap

Roadmap infrastruttura dedicata

Step operativi per rendere Obelica una piattaforma autonoma per progetti cliente

Questa roadmap traduce l'audit del 2026-07-01 in lavoro operativo.

Obiettivo strategico: ridurre e poi rimuovere la dipendenza da Vercel, Neon e servizi equivalenti, mantenendo pero' affidabilita, rollback e documentazione superiori al modello precedente.

Principi

  1. Una app alla volta: niente migrazioni massive di DNS, DB o storage.
  2. Prima evidenza, poi cambio: ogni decisione deve avere check ripetibili.
  3. Ogni cliente ha un contratto operativo: domini, DB, storage, cron, backup, deploy, rollback.
  4. Managed e self-hosted vanno dichiarati: DigitalOcean Managed Postgres puo essere un passaggio intermedio, non va confuso con infrastruttura DB proprietaria.
  5. La documentazione e' parte del deploy: se cambia lo stato reale, cambia Fumadocs.

Mappa priorita

PrioritaTemaPerche conta
P0Stato reale e sicurezza verificabileNon si migra produzione se non si puo provare il perimetro
P1App contractOgni app deve essere noiosa da deployare, monitorare e ripristinare
P1Cron contractLe automazioni clienti devono avere stato, log e alert
P1DB decisionUscire da Neon richiede una scelta esplicita su Postgres managed o self-hosted
P2Healthcheck e risorserunning non basta per dire healthy
P2CI/CD e rollbackSostituisce il valore operativo oggi dato da Vercel
P2OsservabilitaServe storia, non solo check puntuale
P3DR/HANecessario per clienti critici e RTO/RPO migliori

Phase 0 - Truth and evidence

Stato: da fare subito.

Step

  1. Aggiornare current-state con snapshot 2026-07-01.
  2. Aggiornare pagine app/Traefik con domini production gia presenti sul VPS.
  3. Correggere operations/cron-jobs con crontab reale.
  4. Tenere navigazione Fumadocs completa via meta.json.
  5. Creare un comando o runbook per produrre evidenza Cloud Firewall.
  6. Eseguire e salvare evidenza mensile per:
    • sshd -T;
    • ufw status numbered;
    • fail2ban-client status sshd;
    • DigitalOcean Cloud Firewall inbound rules.

Definition of done

  • Fumadocs mostra audit e roadmap.
  • Nessuna pagina operativa importante resta fuori navigazione.
  • current-state non contraddice crontab, router e backup reali.
  • Esiste una procedura per provare che SSH e' limitato a IP fidati.

Phase 1 - App contract

Stato: priorita alta.

Ogni app cliente deve avere una scheda unica con campi obbligatori.

Campi scheda app

CampoObbligatorioNote
Reposipath e branch production
StacksiNext/Astro/Vite/static/monorepo
Containersinome container e compose path
Domini stagingsi*.vps.obelica.com
Domini productionsiapex, www, sottodomini
DNS ownersiVercel, DO, Wix, registrar
DBsinone, DO managed, self-hosted
Storagesinone, Spaces, Cloudinary, legacy Blob
Cronsijob, schedule, timeout, allow-failure
Secretssisolo nomi/categorie, mai valori
Backupsicosa viene salvato e come si ripristina
Smoke testsiendpoint e codici attesi
RollbacksiDNS, container, DB, storage

Step

  1. Creare template content/docs/services/apps/<app>.mdx o sezione equivalente.
  2. Compilare prima le app gia in produzione VPS:
    • tulpa-studio;
    • ottica-style.
  3. Compilare poi app con DB e cron:
    • wash-dog-ferrara;
    • sonja-trekking;
    • macelleria;
    • alessandro-zucchini.
  4. Compilare infine siti statici/senza DB.

Definition of done

  • Ogni app ha una scheda production/staging.
  • obelica deploy list e docs raccontano la stessa realta.
  • Ogni cutover DNS punta a una scheda app completa.

Phase 2 - Cron contract

Stato: critico per uscire da Vercel Cron.

Problema attuale

I cron applicativi sono attivi via crontab e script shell, ma lo stato non e' ancora modellato come piattaforma: non c'e un registro per-job con ultimo run, durata, exit code, output sintetico e policy alert.

Step

  1. Allineare docs al crontab reale.
  2. Portare ogni job sotto control plane Rust:
    • obelica cron list;
    • obelica cron run <job>;
    • obelica cron status.
  3. Salvare per ogni run:
    • timestamp start/end;
    • exit code;
    • durata;
    • output sintetico;
    • app/container target;
    • alert inviato si/no.
  4. Convertire crontab a chiamate control plane, non script diretti.
  5. Definire allow-failure solo dove e' intenzionale e documentato.
  6. Aggiungere alert su job critici falliti.

Definition of done

  • Un cron fallito genera stato consultabile e, se critico, alert.
  • Il bot Telegram mostra stato cron.
  • Nessun job production usa || true senza motivazione documentata.

Phase 3 - Database platform

Stato: decisione strategica aperta.

Scelta A - DigitalOcean Managed Postgres come interim

Vantaggi:

  • meno rischio operativo immediato;
  • backup e patch gestiti;
  • uscita da Neon gia quasi completata.

Obblighi:

  • documentare che non e' ancora DB self-hosted;
  • per-app roles e least privilege;
  • backup logici Obelica indipendenti dal managed provider;
  • restore test periodico;
  • monitoraggio connessioni e storage.

Scelta B - Postgres self-hosted Obelica

Vantaggi:

  • massimo controllo;
  • costo prevedibile;
  • infrastruttura realmente personale.

Obblighi minimi prima della produzione:

  1. cluster Postgres dedicato, non mischiato a Forgejo;
  2. TLS e autenticazione per-app;
  3. ruoli separati per app e migration user;
  4. backup fisici o logici con PITR se richiesto;
  5. restore test automatico;
  6. monitoraggio storage, lock, connessioni, slow query;
  7. piano upgrade Postgres;
  8. runbook incidenti DB;
  9. pooler se le app lo richiedono;
  10. criterio chiaro per dati cliente critici.

Step consigliato

  1. Mantenere DigitalOcean Managed Postgres per i cutover gia in corso.
  2. Progettare un laboratorio Postgres self-hosted non production.
  3. Migrare una app non critica come prova.
  4. Fare restore drill.
  5. Solo dopo, decidere se spostare app production.

Phase 4 - Health, resources and security hardening

Stato: alta priorita.

Step

  1. Aggiungere endpoint /healthz o equivalente alle app dinamiche.
  2. Aggiungere Docker healthcheck per app e servizi interni.
  3. Estendere obelica health per distinguere running da healthy.
  4. Aggiungere resource policy:
    • memoria per Forgejo e app dinamiche;
    • pids_limit;
    • restart alert se un container flappa.
  5. Valutare read_only: true per static app nginx.
  6. Introdurre Docker socket proxy per Traefik e bot.
  7. Ridurre privilegi del runner Forgejo docs o isolarlo per scope.

Definition of done

  • Un'app rotta non passa solo perche il processo e' running.
  • Un singolo container non puo saturare tutto il droplet senza alert.
  • I componenti che leggono Docker socket hanno permessi minimi.

Phase 5 - CI/CD and release model

Stato: necessario per sostituire Vercel come esperienza operativa.

Step

  1. Standardizzare workflow Forgejo per build/test per ogni app.
  2. Definire artifact immagine con tag stabile:
    • app;
    • commit SHA;
    • timestamp;
    • environment.
  3. Aggiungere smoke test automatico post-deploy.
  4. Salvare ultimo deploy riuscito per rollback.
  5. Creare comando:
    • obelica app rollback <app>.
  6. Aggiungere scansione minima:
    • lint;
    • test se presenti;
    • audit dipendenze;
    • build Docker.

Definition of done

  • Un deploy non dipende da passaggi manuali ricordati a memoria.
  • Ogni release e' identificabile e rollbackabile.
  • Il valore operativo di Vercel Deployments viene sostituito da Forgejo + Obelica.

Phase 6 - Observability

Stato: oggi base, da rendere piattaforma.

Step

  1. Rimuovere duplicazione monitor.log se confermata.
  2. Aggiungere metriche storiche:
    • CPU/RAM/swap/disco;
    • container memory/CPU;
    • status endpoint;
    • durata cron;
    • stato backup.
  3. Aggiungere dashboard privata via tunnel.
  4. Definire SLO minimi per app production.
  5. Creare pagina incidenti per ogni evento production.
  6. Aggiungere alert multi-canale solo dopo avere stabilizzato i segnali.

Definition of done

  • Si vede se un problema e' improvviso o trend.
  • Ogni app production ha uptime e cron status consultabile.
  • Gli alert sono pochi, utili e collegati a runbook.

Phase 7 - Backup, restore and disaster recovery

Stato: buono, con gap mirati.

Step

  1. Definire retention remota su Spaces.
  2. Cifrare repos.tar.zst o motivare formalmente perche resta in chiaro.
  3. Automatizzare restore verification periodica su droplet temporaneo o ambiente isolato.
  4. Definire RTO/RPO per classi cliente.
  5. Documentare rebuild completo di obelica-prod da backup.
  6. Tenere runbook DNS rollback per ogni app production.

Definition of done

  • Un backup non e' solo verificato, e' periodicamente ripristinato.
  • Si sa quanto tempo serve a tornare online.
  • I dati cliente hanno RPO dichiarato.

Phase 8 - Scale-out

Stato: non urgente, ma da progettare prima del sovraccarico.

Trigger per aprire questa fase:

  • piu app dinamiche critiche sullo stesso droplet;
  • Forgejo o una app consumano stabilmente oltre il 60% RAM;
  • RTO richiesto inferiore al tempo di restore manuale;
  • necessita di separare staging e production;
  • DB self-hosted production con requisiti forti.

Possibili direzioni:

  • droplet separato per database;
  • droplet separato per app production;
  • droplet staging separato;
  • registry immagini privato;
  • standby restore caldo o tiepido;
  • object storage policy piu rigida;
  • backup cross-region.

Sequenza consigliata

  1. Chiudere Phase 0.
  2. Completare schede app per tulpa-studio e ottica-style.
  3. Sistemare cron contract prima di migrare app con automazioni reali.
  4. Decidere il modello DB.
  5. Aggiungere healthcheck e resource policy.
  6. Estendere CI/CD app per app.
  7. Portare osservabilita e DR a livello clienti.

Stato operativo da tracciare

WorkstreamPrimo artefatto
App contractschede tulpa-studio e ottica-style
Cron contractobelica cron status o file stato per-job
DB platformdecision log managed vs self-hosted
Security evidencerunbook Cloud Firewall/UFW/fail2ban
Observabilitymetriche storiche e dashboard privata
DRretention remota e restore drill schedulato

Nota finale

La piattaforma deve diventare noiosa: ogni migrazione deve sembrare una checklist ripetibile, non un evento eroico.

On this page