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-backupscritto 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,3file; -
monitoraggio base con health check ogni 5 minuti e alert Telegram;
-
build Docker app standardizzate con
.dockerignoree 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.0e containerd a2.2.5il 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-studioealessandro-zucchini; -
cron job da adattare al server e poi riattivare con schedulazione proprietaria.
Decisione domini
Decisione confermata il 2026-06-22:
| Dominio | Ruolo |
|---|---|
*.obelica.com | produzione attuale, da lasciare su Vercel finche' la singola app non e' pronta |
*.vps.obelica.com | staging VPS su Traefik, HTTPS trusted |
vps.obelica.com | hostname base VPS, endpoint diagnostico whoami con HTTPS trusted |
test.obelica.com | test pubblico Traefik/whoami |
Il target DNS per staging VPS e' la reserved IP:
129.212.141.97Container attivi
Infrastruttura
| Container | Image | Stato | Esposizione |
|---|---|---|---|
traefik | traefik:v3.7.1 | running | 0.0.0.0:80, 0.0.0.0:443, 127.0.0.1:8080 |
whoami | traefik/whoami | running | dietro Traefik |
forgejo | codeberg.org/forgejo/forgejo:13 | running | 127.0.0.1:3333 |
forgejo-db | postgres:16-alpine | running, healthy | solo rete Docker interna |
obelica-docs | obelica/obelica-docs:local | running | 127.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| Container | Repo | Stato | Esposizione |
|---|---|---|---|
alessandro-zucchini | bona/alessandro-zucchini | running | dietro Traefik |
caffe-del-corso | bona/caffe-del-corso | running | dietro Traefik |
centro-donna-giustizia | bona/centro-donna-giustizia | running | dietro Traefik |
macelleria | bona/macelleria | running | dietro Traefik |
officina-longhi | bona/officina-longhi | running | dietro Traefik |
ottica-style | bona/ottica-style | running | dietro Traefik |
romauto | bona/romauto | running | dietro Traefik |
sazzini | bona/sazzini | running | dietro Traefik |
sonja-trekking | bona/sonja-trekking | running | dietro Traefik |
tulpa-studio | bona/tulpa-studio | running | dietro Traefik |
wash-dog-admin | bona/wash-dog-ferrara | running | dietro Traefik |
wash-dog-staff | bona/wash-dog-ferrara | running | dietro Traefik |
zannoni | bona/zannoni | running | dietro Traefik |
Stack Compose
| Stack | Path compose | Stato |
|---|---|---|
traefik | /opt/obelica/infra/traefik/docker-compose.yml | running |
whoami | /opt/obelica/apps/whoami/docker-compose.yml | running |
forgejo | /opt/obelica/infra/forgejo/docker-compose.yml | running |
obelica-docs | /opt/obelica/apps/obelica-docs/docker-compose.yml | running |
| app cliente | /opt/obelica/repos/<app>/docker-compose.yml | running |
Porte in ascolto
| Porta | Bind | Servizio | Policy |
|---|---|---|---|
22/tcp | 0.0.0.0, [::] | SSH | pubblico sull'host, limitato dal DigitalOcean Cloud Firewall agli IP fidati |
80/tcp | 0.0.0.0, [::] | Traefik HTTP | pubblico, redirect HTTPS e ACME HTTP challenge |
443/tcp | 0.0.0.0, [::] | Traefik HTTPS | pubblico |
8080/tcp | 127.0.0.1 | Traefik dashboard | solo tunnel SSH |
3333/tcp | 127.0.0.1 | Forgejo HTTP | solo tunnel SSH |
3334/tcp | 127.0.0.1 | Obelica Docs | solo tunnel SSH |
53/tcp/udp | loopback | systemd-resolved | locale |
Servizi systemd rilevati
| Servizio | Stato |
|---|---|
docker | active |
ssh | active |
fail2ban | active |
ufw | active |
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
bonaappartiene al gruppodocker, quindi ha potere operativo equivalente a root tramite Docker. - I domini staging
*.vps.obelica.comsono allineati al droplet e hanno certificati trusted. - I domini produzione restano su Vercel/hosting esistente fino alla migrazione app per app;
tulpa-studioe' 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-statusper il monitoraggio. - Risolto il 2026-06-26 un
Permission deniedcausato da filetarget/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;
.dockerignorestandard 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-prodeobelica-assets-staginginfra1, CDN abilitato; - definizione policy storage: target Vercel Blob reali
sonja-trekkingetulpa-studio;alessandro-zucchiniusa Cloudinary, quindi e' migrazione separata; esclusi per orawash-dog-ferraraeobelica. - audit produzione Vercel storage:
sonja-trekkingha 57 oggetti Blob;tulpa-studioha 267 oggetti Blob, 327 riferimenti DB e 210 URL Blob unici;alessandro-zucchiniha 28 riferimenti Cloudinary e nessun Blob token. - migrazione production
sonja-trekkingda Vercel Blob a DigitalOcean Spaces completata: DB production senza URL Blob, 46 URL Spaces verificati HTTP 200,STORAGE_PROVIDER=spacesattivo in Vercel Production. - migrazione production
tulpa-studioda 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=spacesattivo in Vercel Production. - migrazione production
alessandro-zucchinida 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=spacesattivo in Vercel Production. - audit env key-only per tutte le app containerizzate: tutti gli env file VPS esistono; per
tulpa-studio,sonja-trekkingealessandro-zucchinierano assenti sul VPS le chiavi Spaces necessarie al runtime production;tulpa-studioe' stato riallineato. - preparazione pilota DNS
tulpa-studio: repo VPS aggiornato a codice Spaces, env production normalizzato, router Traefik esteso atulpastudio.comewww.tulpastudio.com, rebuild container riuscito, smoke staging e smoke pre-DNS concurl --resolveHTTP 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-040001verificato anche offsite; - smoke test HTTPS completo su staging VPS e
tulpastudio.comOK.
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.shriallineato per chiamare il deploy Rust; deploy allcompletato 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, zannoniNota 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
middlewaredeprecato, 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.zstora 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 tokenwrite:repositorydatati (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
NOPASSWDmirato per azzerare gli UNKNOWN dihealth.sh(ufw/fail2ban). - Env Spaces allineati: sonja-trekking in produzione usava ancora Vercel
Blob (
STORAGE_PROVIDERassente) — 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_KEYin 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 CUTOVERnei 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_dbincluso nei backup viasecrets/apps/obelica.env(prima: zero backup per il DB del progetto Obelica).- Retention offsite attiva: nuovo comando
obelica backup lifecycle, applicati 90 giorni suauto/+ 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-pickcon origin sul bare repo locale; - container
first-pick(nginx:alpinestatico) dietro Traefik, router condesign.firstpick.fun+ stagingfirst-pick.vps.obelica.comcome SAN, certificato Let's Encrypt emesso; - zona DNS
firstpick.funsu DigitalOcean, record Adesignverso129.212.141.97(apex ancora senza record, arrivera' con la landing); - target
static-dockeraggiunto adeploy-apps.tsve riga instaging-apps.tsv; backup config pre-modifica inbackups/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.