Obelica Docs

Stato attuale

Snapshot operativo del droplet Obelica

Snapshot verificato il 2026-06-24 dal server /opt/obelica, dai router pubblici Traefik e dai deploy production Vercel coinvolti.

Nota 2026-07-03: questo snapshot e' antecedente ai cutover di luglio (8 domini production gia' sul VPS — vedi Applications e Migrations) e va rigenerato. Gli interventi del 2026-07-03 sono elencati in fondo alla pagina.

Sintesi

Obelica e' un singolo droplet DigitalOcean in regione FRA1, con Docker Compose come runtime, Traefik come reverse proxy pubblico, Forgejo privato via tunnel SSH, Postgres in Docker per Forgejo e DigitalOcean managed PostgreSQL per le app in preparazione/migrazione.

Il modello attuale e' volutamente semplice:

  • un solo droplet;

  • un solo ingresso pubblico applicativo su Traefik 80/443;

  • servizi amministrativi legati a 127.0.0.1;

  • Git privato tramite Forgejo;

  • database managed per le app, Postgres locale solo per Forgejo;

  • backup automatico quotidiano con obelica-backup scritto in Rust, sync offsite su Spaces, retention locale a 1 snapshot e wrapper cron che scrive stato per il monitoraggio;

  • produzione attuale delle app ancora su Vercel;

  • ambiente VPS usato come staging/hosting target con DNS/TLS staging attivo;

  • Spaces DigitalOcean creati per asset produzione/staging, da usare solo sulle app con storage reale;

  • smoke test globale staging verde;

  • log Docker limitati con rotazione json-file, 10m, 3 file;

  • monitoraggio base con health check ogni 5 minuti e alert Telegram;

  • build Docker app standardizzate con .dockerignore e cache mount BuildKit dove applicabile;

  • deploy applicativo centralizzato nel control plane Rust obelica, con target configurati in /opt/obelica/infra/config/deploy-apps.tsv;

  • Docker Engine aggiornato a 29.6.0 e containerd a 2.2.5 il 2026-06-24;

  • tutti gli update apt disponibili applicati il 2026-06-24, nessun reboot richiesto;

  • disco root intorno al 67% dopo rebuild completo di tutte le app; la crescita e' principalmente build cache Docker reclaimable;

  • futura migrazione app per app da Vercel a DigitalOcean;

  • migrazione storage a Spaces completata per sonja-trekking, tulpa-studio e alessandro-zucchini;

  • cron job da adattare al server e poi riattivare con schedulazione proprietaria.

Decisione domini

Decisione confermata il 2026-06-22:

DominioRuolo
*.obelica.comproduzione attuale, da lasciare su Vercel finche' la singola app non e' pronta
*.vps.obelica.comstaging VPS su Traefik, HTTPS trusted
vps.obelica.comhostname base VPS, endpoint diagnostico whoami con HTTPS trusted
test.obelica.comtest pubblico Traefik/whoami

Il target DNS per staging VPS e' la reserved IP:

129.212.141.97

Container attivi

Infrastruttura

ContainerImageStatoEsposizione
traefiktraefik:v3.7.1running0.0.0.0:80, 0.0.0.0:443, 127.0.0.1:8080
whoamitraefik/whoamirunningdietro Traefik
forgejocodeberg.org/forgejo/forgejo:13running127.0.0.1:3333
forgejo-dbpostgres:16-alpinerunning, healthysolo rete Docker interna
obelica-docsobelica/obelica-docs:localrunning127.0.0.1:3334

App cliente / gestionali su VPS

Questi container sono running sul droplet e pubblicati su *.vps.obelica.com con HTTPS trusted. Non rappresentano ancora migrazione produzione completata: vanno trattati come staging/candidate deploy finche' cron, feature specifiche e smoke test non sono verificati app per app.

Smoke test globale verificato il 2026-06-22:

OK:      96
WARN:    0
UNKNOWN: 0
FAIL:    0
ContainerRepoStatoEsposizione
alessandro-zucchinibona/alessandro-zucchinirunningdietro Traefik
caffe-del-corsobona/caffe-del-corsorunningdietro Traefik
centro-donna-giustiziabona/centro-donna-giustiziarunningdietro Traefik
macelleriabona/macelleriarunningdietro Traefik
officina-longhibona/officina-longhirunningdietro Traefik
ottica-stylebona/ottica-stylerunningdietro Traefik
romautobona/romautorunningdietro Traefik
sazzinibona/sazzinirunningdietro Traefik
sonja-trekkingbona/sonja-trekkingrunningdietro Traefik
tulpa-studiobona/tulpa-studiorunningdietro Traefik
wash-dog-adminbona/wash-dog-ferrararunningdietro Traefik
wash-dog-staffbona/wash-dog-ferrararunningdietro Traefik
zannonibona/zannonirunningdietro Traefik

Stack Compose

StackPath composeStato
traefik/opt/obelica/infra/traefik/docker-compose.ymlrunning
whoami/opt/obelica/apps/whoami/docker-compose.ymlrunning
forgejo/opt/obelica/infra/forgejo/docker-compose.ymlrunning
obelica-docs/opt/obelica/apps/obelica-docs/docker-compose.ymlrunning
app cliente/opt/obelica/repos/<app>/docker-compose.ymlrunning

Porte in ascolto

PortaBindServizioPolicy
22/tcp0.0.0.0, [::]SSHpubblico sull'host, limitato dal DigitalOcean Cloud Firewall agli IP fidati
80/tcp0.0.0.0, [::]Traefik HTTPpubblico, redirect HTTPS e ACME HTTP challenge
443/tcp0.0.0.0, [::]Traefik HTTPSpubblico
8080/tcp127.0.0.1Traefik dashboardsolo tunnel SSH
3333/tcp127.0.0.1Forgejo HTTPsolo tunnel SSH
3334/tcp127.0.0.1Obelica Docssolo tunnel SSH
53/tcp/udploopbacksystemd-resolvedlocale

Servizi systemd rilevati

ServizioStato
dockeractive
sshactive
fail2banactive
ufwactive

Stato sicurezza sintetico

  • Forgejo non e' pubblico.
  • Traefik dashboard non e' pubblica.
  • Docs non sono pubbliche.
  • Postgres Forgejo non pubblica porte host.
  • UFW e' attivo, ma le regole richiedono root per essere lette.
  • Il DigitalOcean Cloud Firewall e' il controllo principale dichiarato per limitare SSH.
  • L'utente operativo bona appartiene al gruppo docker, quindi ha potere operativo equivalente a root tramite Docker.
  • I domini staging *.vps.obelica.com sono allineati al droplet e hanno certificati trusted.
  • I domini produzione restano su Vercel/hosting esistente fino alla migrazione app per app; tulpa-studio e' preparato lato VPS come pilota DNS, ma il DNS pubblico non e' ancora stato spostato.
  • Lo smoke test staging controlla DNS, TLS, container e router Traefik prima di considerare conclusa una modifica pubblica.

Backup

  • Backup automatico giornaliero alle 04:00 con obelica-backup tramite wrapper cron.
  • Backup cifrati con ChaCha20Poly1305; permessi file 600.
  • Retention locale: 1 snapshot completo.
  • Backup offsite attivo su DigitalOcean Spaces Cold Storage obelica-backups-prod.
  • Il job giornaliero esegue backup, sync offsite, verifica manifest offsite e prune locale.
  • Stato ultimo backup scritto in /opt/obelica/backups/last-backup-status per il monitoraggio.
  • Risolto il 2026-06-26 un Permission denied causato da file target/ root-owned nei build Rust.

Operativita recente

Il 2026-06-22 sono stati aggiunti:

  • /opt/obelica/infra/scripts/check-staging-apps.sh;
  • /opt/obelica/infra/config/staging-apps.tsv;
  • comando locale obelica smoke staging;
  • log rotation Docker su app staging e servizi infrastrutturali principali;
  • .dockerignore standard e cache mount BuildKit nei Dockerfile delle app staging;
  • rebuild e recreate completo delle app staging, verificato con obelica smoke staging;
  • pulizia controllata Docker build cache: disco root da 76% durante rebuild a 51% dopo prune, build cache intorno a 7.6 GB.
  • creazione Spaces obelica-assets-prod e obelica-assets-staging in fra1, CDN abilitato;
  • definizione policy storage: target Vercel Blob reali sonja-trekking e tulpa-studio; alessandro-zucchini usa Cloudinary, quindi e' migrazione separata; esclusi per ora wash-dog-ferrara e obelica.
  • audit produzione Vercel storage: sonja-trekking ha 57 oggetti Blob; tulpa-studio ha 267 oggetti Blob, 327 riferimenti DB e 210 URL Blob unici; alessandro-zucchini ha 28 riferimenti Cloudinary e nessun Blob token.
  • migrazione production sonja-trekking da Vercel Blob a DigitalOcean Spaces completata: DB production senza URL Blob, 46 URL Spaces verificati HTTP 200, STORAGE_PROVIDER=spaces attivo in Vercel Production.
  • migrazione production tulpa-studio da Vercel Blob a DigitalOcean Spaces completata: 267 oggetti copiati, 254 righe DB aggiornate, 0 URL Blob residui, 210 URL Spaces verificati HTTP 200, STORAGE_PROVIDER=spaces attivo in Vercel Production.
  • migrazione production alessandro-zucchini da Cloudinary a DigitalOcean Spaces completata: 17 asset copiati, 24 righe DB aggiornate, 2 riferimenti cover 404 riparati, 0 URL Cloudinary residui nel DB, 17 URL Spaces verificati HTTP 200, STORAGE_PROVIDER=spaces attivo in Vercel Production.
  • audit env key-only per tutte le app containerizzate: tutti gli env file VPS esistono; per tulpa-studio, sonja-trekking e alessandro-zucchini erano assenti sul VPS le chiavi Spaces necessarie al runtime production; tulpa-studio e' stato riallineato.
  • preparazione pilota DNS tulpa-studio: repo VPS aggiornato a codice Spaces, env production normalizzato, router Traefik esteso a tulpastudio.com e www.tulpastudio.com, rebuild container riuscito, smoke staging e smoke pre-DNS con curl --resolve HTTP 200.

Il 2026-06-24 e' stato applicato l'update Docker/containerd:

  • Docker Engine 29.6.0;
  • containerd 2.2.5;
  • nessun reboot richiesto;
  • tutti i container running dopo restart Docker;
  • health, backup offsite verify e smoke test HTTPS pubblici OK.

Successivamente sono stati applicati anche gli ultimi update Ubuntu residui (kpartx e multipath-tools). Post-check finale:

  • nessun pacchetto residuo in apt list --upgradable;
  • nessun reboot richiesto;
  • tutti i container running;
  • ultimo backup giornaliero 20260624-040001 verificato anche offsite;
  • smoke test HTTPS completo su staging VPS e tulpastudio.com OK.

Il 2026-06-24 e' stato introdotto e verificato il deploy centralizzato Rust:

  • file config target: /opt/obelica/infra/config/deploy-apps.tsv;
  • comando lista: /opt/obelica/infra/bin/obelica deploy list;
  • comando singola app: /opt/obelica/infra/bin/obelica app deploy <name>;
  • comando docs: /opt/obelica/infra/bin/obelica deploy docs;
  • comando completo: /opt/obelica/infra/bin/obelica deploy all;
  • wrapper /opt/obelica/infra/scripts/deploy-obelica-docs.sh riallineato per chiamare il deploy Rust;
  • deploy all completato su 14 target con container check e smoke 200;
  • obelica health: OK post-deploy;
  • obelica backup verify-offsite: OK su ultimo backup giornaliero.

Target deploy verificati:

obelica-docs, alessandro-zucchini, caffe-del-corso,
centro-donna-giustizia, macelleria, officina-longhi, ottica-style,
wash-dog-ferrara, zannoni

Nota operativa: il binario globale /usr/local/bin/obelica puo' restare una copia precedente finche' non viene promosso con sudo. Usare il path esplicito /opt/obelica/infra/bin/obelica per i deploy.

Backup config creati prima delle modifiche:

  • /opt/obelica/backups/configs/pre-staging-smoke-20260622-103414;
  • /opt/obelica/backups/configs/pre-log-rotation-20260622-104009;
  • /opt/obelica/backups/configs/pre-runner-log-rotation-20260622-104330.

Monitoraggio

  • Health check ogni 5 minuti tramite /opt/obelica/infra/monitoring/check-health.sh.
  • Alert su Telegram per disco, memoria, container down, servizi down, backup fallito, endpoint HTTPS down e certificato in scadenza.
  • Deduplicazione alert tramite /opt/obelica/infra/monitoring/last-monitor-status.
  • Vedi Monitoraggio e alert per i dettagli.

Gap aperti

  • Verifica manuale periodica del DigitalOcean Cloud Firewall.
  • Restore completo su droplet temporaneo.
  • CI/CD da Forgejo.
  • Infrastruttura proprietaria per cron job.
  • Heartbeat giornaliero OK e raccolta metriche storiche (Prometheus/Grafana).
  • Supporto alert multi-canale oltre a Telegram.
  • Monitoraggio post-migrazione storage Spaces per le app gia' migrate e verifica manuale periodica degli upload admin.
  • Migrazioni storage future solo per app con requisito reale confermato.
  • Ottimizzazione app-specific di asset/repo pesanti, soprattutto tulpa-studio.
  • Policy automatizzata o comando dedicato per limitare build cache Docker dopo rebuild massivi.
  • Hardening applicativo emerso dai build: npm audit high/critical, warning Next middleware deprecato, warning Turbopack/NFT Wash Dog, config Next da rivedere app per app.

Interventi 2026-07-03

Sessione di hardening sicurezza backup/segreti (dettagli nelle pagine linkate):

  • Escrow passphrase backup creato fuori dal droplet e verificato via hash (obelica-backup).
  • repos.tar.zst ora cifrato nel backup offsite; corretto anche il path stale del binario nel control plane (infra/bin/obelica-backup); pipeline completa e percorso di restore verificati con run manuale.
  • Token Forgejo ruotati: revocati gli ultimi due token scope all, sostituiti da token write:repository datati (secrets).
  • Cloud Firewall verificato via doctl per la prima volta: conforme, SSH filtrato a singolo IP (firewall). Resta aperta l'automazione periodica della verifica e il sudoers NOPASSWD mirato per azzerare gli UNKNOWN di health.sh (ufw/fail2ban).
  • Env Spaces allineati: sonja-trekking in produzione usava ancora Vercel Blob (STORAGE_PROVIDER assente) — env corretto, restart container in attesa di finestra; alessandro-zucchini (staging) corretto, ricreato e verificato (sonja-trekking, alessandro-zucchini).
  • Consolidato il working tree docs: ~40 file (applications/, migrazioni luglio, audit 2026-07-01) erano non committati e quindi fuori dai bundle git del backup; ora committati e pushati.

Secondo batch (pomeriggio) — fix operativi dall'audit completo

  • wash-dog-staff voice-report riparata: mancava AI_GATEWAY_API_KEY in produzione (chiave team riusata, TODO chiave dedicata) — vedi scheda app.
  • Loop ACME chiuso: domini production rimossi dai router pre-cutover di tulpa-studio, alessandro-zucchini e centro-donna-giustizia (commento AL CUTOVER nei compose con le righe da riattivare); commit+push.
  • Remote git normalizzati su tutti i 14 repo: 12 avevano il vecchio token revocato embedded nell'URL — deploy pipeline sarebbe fallita ovunque.
  • obelica_db incluso nei backup via secrets/apps/obelica.env (prima: zero backup per il DB del progetto Obelica).
  • Retention offsite attiva: nuovo comando obelica backup lifecycle, applicati 90 giorni su auto/ + abort multipart 7 giorni.
  • Alert Telegram sui deploy falliti in tutti i 13 workflow + template.
  • Igiene: villa-ebe commentata in staging-apps.tsv; fix log duplicati (monitor + backup wrapper); docker builder prune (7,7 GB recuperati); token snapshot archiviato sulla workstation e rimosso dal droplet.

Autodeploy attivo per tutte le 14 app (sera): il drift dei compose (label cutover mai committate) bloccava la guardia anti-dirty del deploy per 9 app. Risolto: drift committato repo per repo (pilota zannoni, poi le altre 8), 9/9 run verdi, ogni container ricreato con blip di pochi secondi, smoke completo post-deploy 10/10 siti 200. git status pulito su tutti i 14 repo: git coincide con la produzione. Bonifiche collaterali: ripristinato il package-lock.json di sonja (churn di un npm install di manutenzione), archiviato il compose .bak orfano di wash-dog in removed/.

Flusso operativo da ora: push su main (o master per centro-donna-giustizia) → Forgejo Actions → build → recreate → smoke test → in caso di fallimento, alert Telegram.

Restano in attesa di finestra concordata: reboot kernel + apt upgrade; UFW restrizione porta 22 (serve sudo interattivo); hardening container (healthcheck/limiti, Fase 2).

Interventi 2026-07-10

Nuova app first-pick (progetto interno First Pick, design system statico su design.firstpick.fun) — prima app nativa VPS, mai passata da Vercel:

  • repo Forgejo bona/first-pick, checkout /opt/obelica/repos/first-pick con origin sul bare repo locale;
  • container first-pick (nginx:alpine statico) dietro Traefik, router con design.firstpick.fun + staging first-pick.vps.obelica.com come SAN, certificato Let's Encrypt emesso;
  • zona DNS firstpick.fun su DigitalOcean, record A design verso 129.212.141.97 (apex ancora senza record, arrivera' con la landing);
  • target static-docker aggiunto a deploy-apps.tsv e riga in staging-apps.tsv; backup config pre-modifica in backups/configs/pre-first-pick-20260710-115108;
  • secrets placeholder /opt/obelica/secrets/apps/first-pick.env (vuoto);
  • autodeploy attivo dal primo giorno: prima run Actions verde, smoke https://design.firstpick.fun/ 200, smoke staging globale 96 OK / 0 FAIL.

Dettagli nella scheda First Pick.

On this page