← All documentation

Goooy Developer Guide

The technical foundations for the people who build, deploy, and integrate Goooy: what the system is made of, how to deploy it, and how it’s configured.

Goooy is a complete groupware suite you host yourself: mail, calendar, contacts, tasks, notes, chat, files, video meetings, collaborative office, and an admin console, all from one application, one data model, and one Helm chart. You own the servers, the data, and the keys.

This guide covers the platform itself. Day-to-day operation (the admin console, organizations & users, authentication policy, the mail server, device management, migration, multi-tenancy, and backups) is the Administrator Guide; the end-user’s view of the apps is the User Guide. For deep technical detail, the docs/ folder in the product source has dedicated references (architecture, security, mail server, tenancy, deployment, migration, and the native-client protocols).

Contents


What you’re running

Goooy is a modular monolith: a single Fastify/TypeScript API backed by PostgreSQL, Redis, and S3-compatible object storage, plus a React single-page web app served by nginx. Native clients (Outlook, Thunderbird, Apple Mail, phones) connect over the standard protocols. Optionally, a real mail server (Postfix + Dovecot + Rspamd) turns the API into the delivery hub for inbound and outbound internet mail.

   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)  │
                       └──────────┘  └────────┘  └──────────┘

Backing services and what they hold:

StoreRoleIf it’s lost
PostgreSQLSystem of record: all structured data and the webmail view of messagesCatastrophic; this is what you back up
S3 / MinIOOpaque blobs: file uploads (versioned) and mail attachmentsFile/attachment content lost
RedisEphemeral only: realtime pub/sub, presence, meeting rostersRealtime degrades briefly; no durable data lost

The whole suite ships as a Helm chart (deploy/helm/goooy) that can bundle Postgres/Redis/MinIO for you or point at managed external instances.


Deploying Goooy

A minimal install brings up the full suite: api + web Deployments, bundled PostgreSQL/Redis/MinIO, and an Ingress that path-routes the app and every native-client protocol path:

helm install goooy ./deploy/helm/goooy \
  --namespace goooy --create-namespace \
  --set ingress.host=mail.example.com

The Ingress routes / to the web app and /api, /ws, /dav, /share, /autodiscover, /.well-known/autoconfig, /mail/config, and /Microsoft-Server-ActiveSync to the API. TLS terminates here.

Bundled vs. external backing services. Each store can be bundled (the default) or external:

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=…

Production hardening. Turn on autoscaling, disruption budgets, nightly backups, automatic TLS, and your own 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

Every knob is documented in deploy/helm/goooy/values.yaml; the full topology is in Deployment.

Local evaluation (Docker Compose)

To try Goooy on a laptop:

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

Open http://localhost:5173 and sign in as the bootstrap admin. Two demo users (alice@goooy.local / bob@goooy.local, password demo) let you send mail between accounts and watch local delivery work.

Container images

Multi-stage builds, all running non-root (uid 1000) under a restrictive pod security context:

  • api: Node 22, runs prisma migrate deploy then the server; exposes HTTP (4000) and the SMTP/LMTP ingest ports (2525/2526).
  • web: Vite build served by nginx; reverse-proxies /api, /ws, and the protocol paths, sets security headers, and does SPA fallback.
  • marketing: a static Astro public site (optional; see the Administrator Guide).
  • mail: Postfix, Dovecot, Rspamd (only when the mail server is enabled).

Configuration essentials

Configuration is centralized and Zod-validated at boot. The API fails fast if JWT_SECRET (≥16 chars) or DATABASE_URL is missing or invalid, so a misconfigured deployment never starts in a half-broken state. Everything else has sensible defaults.

The most important variables:

GroupKey variables
CorePUBLIC_WEB_URL, PUBLIC_API_URL, API_PORT (4000)
Auth (required)JWT_SECRET (≥16 chars), JWT_ACCESS_TTL (900s), JWT_REFRESH_TTL (30d)
Data (required)DATABASE_URL, REDIS_URL
Object storageS3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY / S3_SECRET_KEY
Mail (outbound)SMTP_HOST / SMTP_PORT / SMTP_SECURE
Mail (inbound)SMTP_INGEST_*, LMTP_INGEST_*, RSPAMD_URL, DOVECOT_LMTP_*
MeetMEET_ICE_SERVERS (STUN/TURN servers as JSON)
BootstrapBOOTSTRAP_ORG / BOOTSTRAP_DOMAIN / BOOTSTRAP_ADMIN_EMAIL / BOOTSTRAP_ADMIN_PASSWORD

Secrets. JWT_SECRET and DATABASE_URL should come from a Kubernetes Secret you supply (secret.existingSecret). Never ship the chart default into production. JWT_SECRET does double duty: it also seals S/MIME private keys, SSO client secrets, and migration credentials at rest, so changing it invalidates those sealed values. Rotate deliberately. The full env table is in Deployment.


Where to go next

  • The Administrator Guide covers running the deployed suite: the admin console, organizations & users, authentication policy, the mail server, device management, migration, multi-tenancy, and backups.
  • The User Guide is the end-user view of every app.
  • The full technical reference (architecture, data model, mail server, tenancy, deployment, migration, and the native-client protocols) ships with the product source.