Guida per sviluppatori di Goooy
Le fondamenta tecniche per chi costruisce, distribuisce e integra Goooy: di cosa è fatto il sistema, come distribuirlo e come viene configurato.
Goooy è una suite groupware completa che ospiti tu stesso: posta, calendario, contatti, attività, note, chat, file, videoriunioni, office collaborativo e una console di amministrazione, tutto da un’unica applicazione, un unico modello di dati e un unico Helm chart. Sei tu il proprietario dei server, dei dati e delle chiavi.
Questa guida copre la piattaforma stessa. La gestione quotidiana (la console di
amministrazione, organizzazioni e utenti, la policy di autenticazione, il server di
posta, la gestione dei dispositivi, la migrazione, la multi-tenancy e i backup) è
trattata nella Guida per l’amministratore; la visione delle
app dal punto di vista dell’utente finale è nella
Guida utente. Per i dettagli tecnici approfonditi, la
cartella docs/ nel codice sorgente del prodotto contiene riferimenti dedicati
(architettura, sicurezza, server di posta, tenancy, deployment, migrazione e i
protocolli client nativi).
Indice
Cosa stai eseguendo
Goooy è un monolite modulare: un’unica API Fastify/TypeScript basata su PostgreSQL, Redis e object storage compatibile con S3, più un’app web single-page in React servita da nginx. I client nativi (Outlook, Thunderbird, Apple Mail, telefoni) si collegano tramite i protocolli standard. Facoltativamente, un vero server di posta (Postfix + Dovecot + Rspamd) trasforma l’API nell’hub di consegna per la posta internet in entrata e in uscita.
Browser ───────▶ web (React SPA, nginx) ──proxies /api, /ws──▶
Native clients ─▶ api (Fastify, modular monolith)
(DAV · EAS · │ │ │
Autodiscover · ┌───────▼──┐ ┌───▼────┐ ┌──▼───────┐
IMAP/POP3/SMTP) │PostgreSQL│ │ Redis │ │ S3/MinIO │
│ (Prisma) │ │pub/sub │ │ (blobs) │
└──────────┘ └────────┘ └──────────┘
Servizi di supporto e cosa contengono:
| Store | Ruolo | Se viene perso |
|---|---|---|
| PostgreSQL | Sistema di riferimento: tutti i dati strutturati e la vista webmail dei messaggi | Catastrofico; è questo ciò di cui fare il backup |
| S3 / MinIO | Blob opachi: caricamenti di file (versionati) e allegati email | Contenuto di file/allegati perso |
| Redis | Solo effimero: pub/sub in tempo reale, presenza, elenchi partecipanti alle riunioni | Il tempo reale si degrada brevemente; nessun dato durevole perso |
L’intera suite viene fornita come Helm chart (deploy/helm/goooy) che può
includere Postgres/Redis/MinIO per te oppure puntare a istanze esterne gestite.
Distribuire Goooy
Kubernetes (consigliato)
Un’installazione minima avvia l’intera suite: i Deployment api + web,
PostgreSQL/Redis/MinIO inclusi e un Ingress che instrada per percorso l’app e ogni
percorso di protocollo dei client nativi:
helm install goooy ./deploy/helm/goooy \
--namespace goooy --create-namespace \
--set ingress.host=mail.example.com
L’Ingress instrada / verso l’app web e /api, /ws, /dav, /share,
/autodiscover, /.well-known/autoconfig, /mail/config e
/Microsoft-Server-ActiveSync verso l’API. Il TLS termina qui.
Servizi di supporto inclusi o esterni. Ogni store può essere incluso (impostazione predefinita) oppure esterno:
helm install goooy ./deploy/helm/goooy \
--set postgresql.enabled=false --set externalDatabase.url=postgresql://… \
--set redis.enabled=false --set externalRedis.url=redis://… \
--set minio.enabled=false --set externalS3.endpoint=https://s3… \
--set externalS3.accessKey=… --set externalS3.secretKey=…
Hardening di produzione. Attiva autoscaling, disruption budget, backup notturni, TLS automatico e il tuo secret:
helm upgrade goooy ./deploy/helm/goooy \
--set autoscaling.enabled=true \ # HPA for api + web (needs metrics-server)
--set podDisruptionBudget.enabled=true \
--set backup.enabled=true \ # nightly pg_dump CronJob
--set ingress.tls.clusterIssuer=letsencrypt-prod \
--set secret.existingSecret=goooy-prod-secret
Ogni parametro è documentato in
deploy/helm/goooy/values.yaml; la topologia
completa è in Deployment.
Valutazione locale (Docker Compose)
Per provare Goooy su un portatile:
cp .env.example .env # sets JWT_SECRET, DATABASE_URL, …
docker compose up -d postgres redis minio mailpit # backing services
npm install
npm run db:migrate --workspace @goooy/api # apply schema
npm run db:seed --workspace @goooy/api # bootstrap org + admin + demo users
npm run dev # api :4000 + web :5173
Apri http://localhost:5173 e accedi come amministratore di bootstrap. Due utenti
demo (alice@goooy.local / bob@goooy.local, password demo) ti permettono di
inviare posta tra gli account e di osservare la consegna locale in azione.
Immagini container
Build multi-stage, tutte eseguite come non-root (uid 1000) sotto un pod security context restrittivo:
- api: Node 22, esegue
prisma migrate deploye poi il server; espone HTTP (4000) e le porte di ingest SMTP/LMTP (2525/2526). - web: build Vite servita da nginx; fa da reverse proxy per
/api,/wse i percorsi di protocollo, imposta gli header di sicurezza ed esegue il fallback SPA. - marketing: un sito pubblico statico in Astro (facoltativo; vedi la Guida per l’amministratore).
- mail: Postfix, Dovecot, Rspamd (solo quando il server di posta è abilitato).
Configurazione essenziale
La configurazione è centralizzata e validata con Zod all’avvio. L’API si
arresta immediatamente se JWT_SECRET (≥16 caratteri) o DATABASE_URL mancano o
non sono validi, così un deployment mal configurato non si avvia mai in uno stato
semi-funzionante. Tutto il resto ha valori predefiniti ragionevoli.
Le variabili più importanti:
| Gruppo | Variabili principali |
|---|---|
| Base | PUBLIC_WEB_URL, PUBLIC_API_URL, API_PORT (4000) |
| Autenticazione (obbligatoria) | JWT_SECRET (≥16 caratteri), JWT_ACCESS_TTL (900s), JWT_REFRESH_TTL (30d) |
| Dati (obbligatori) | DATABASE_URL, REDIS_URL |
| Object storage | S3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY / S3_SECRET_KEY |
| Posta (in uscita) | SMTP_HOST / SMTP_PORT / SMTP_SECURE |
| Posta (in entrata) | SMTP_INGEST_*, LMTP_INGEST_*, RSPAMD_URL, DOVECOT_LMTP_* |
| Riunioni | MEET_ICE_SERVERS (server STUN/TURN in formato JSON) |
| Bootstrap | BOOTSTRAP_ORG / BOOTSTRAP_DOMAIN / BOOTSTRAP_ADMIN_EMAIL / BOOTSTRAP_ADMIN_PASSWORD |
Secret.
JWT_SECRETeDATABASE_URLdovrebbero provenire da un Kubernetes Secret che fornisci tu (secret.existingSecret). Non portare mai il valore predefinito del chart in produzione.JWT_SECRETsvolge un doppio ruolo: sigilla anche le chiavi private S/MIME, i secret client SSO e le credenziali di migrazione a riposo, quindi modificarlo invalida quei valori sigillati. Ruotalo con cautela. La tabella completa delle variabili d’ambiente è in Deployment.
Dove proseguire
- La Guida per l’amministratore copre la gestione della suite distribuita: la console di amministrazione, organizzazioni e utenti, la policy di autenticazione, il server di posta, la gestione dei dispositivi, la migrazione, la multi-tenancy e i backup.
- La Guida utente è la visione di ogni app dal punto di vista dell’utente finale.
- Il riferimento tecnico completo (architettura, modello di dati, server di posta, tenancy, deployment, migrazione e i protocolli client nativi) è incluso nel codice sorgente del prodotto.