← Toda la documentación

Guía del desarrollador de Goooy

Los fundamentos técnicos para quienes construyen, despliegan e integran Goooy: de qué está hecho el sistema, cómo desplegarlo y cómo se configura.

Goooy es una suite de groupware completa que alojas tú mismo: correo, calendario, contactos, tareas, notas, chat, archivos, videorreuniones, ofimática colaborativa y una consola de administración, todo desde una única aplicación, un único modelo de datos y un único chart de Helm. Tú eres el dueño de los servidores, los datos y las claves.

Esta guía cubre la plataforma en sí. La operación del día a día (la consola de administración, organizaciones y usuarios, la política de autenticación, el servidor de correo, la gestión de dispositivos, la migración, la multitenencia y las copias de seguridad) está en la Guía del administrador; la visión de las aplicaciones desde el punto de vista del usuario final está en la Guía del usuario. Para obtener detalles técnicos profundos, la carpeta docs/ del código fuente del producto contiene referencias específicas (arquitectura, seguridad, servidor de correo, multitenencia, despliegue, migración y los protocolos de cliente nativo).

Contenido


Qué estás ejecutando

Goooy es un monolito modular: una única API de Fastify/TypeScript respaldada por PostgreSQL, Redis y almacenamiento de objetos compatible con S3, además de una aplicación web de página única en React servida por nginx. Los clientes nativos (Outlook, Thunderbird, Apple Mail, teléfonos) se conectan mediante los protocolos estándar. Opcionalmente, un servidor de correo real (Postfix + Dovecot + Rspamd) convierte la API en el centro de entrega del correo de internet entrante y saliente.

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

Servicios de respaldo y qué almacenan:

AlmacénFunciónSi se pierde
PostgreSQLSistema de referencia: todos los datos estructurados y la vista de webmail de los mensajesCatastrófico; esto es lo que respaldas
S3 / MinIOBlobs opacos: archivos subidos (con versiones) y adjuntos de correoSe pierde el contenido de archivos/adjuntos
RedisSolo efímero: pub/sub en tiempo real, presencia, listas de participantes de reunionesEl tiempo real se degrada brevemente; no se pierde ningún dato duradero

Toda la suite se distribuye como un chart de Helm (deploy/helm/goooy) que puede incluir Postgres/Redis/MinIO por ti o apuntar a instancias externas gestionadas.


Desplegar Goooy

Kubernetes (recomendado)

Una instalación mínima levanta la suite completa: los Deployments de api + web, PostgreSQL/Redis/MinIO incluidos y un Ingress que enruta por ruta la aplicación y cada ruta de protocolo de cliente nativo:

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

El Ingress enruta / a la aplicación web y /api, /ws, /dav, /share, /autodiscover, /.well-known/autoconfig, /mail/config y /Microsoft-Server-ActiveSync a la API. TLS termina aquí.

Servicios de respaldo incluidos frente a externos. Cada almacén puede estar incluido (lo predeterminado) o ser externo:

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

Refuerzo para producción. Activa el autoescalado, los presupuestos de interrupción, las copias de seguridad nocturnas, el TLS automático y tu propio secreto:

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

Cada parámetro está documentado en deploy/helm/goooy/values.yaml; la topología completa está en Despliegue.

Evaluación local (Docker Compose)

Para probar Goooy en un portátil:

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

Abre http://localhost:5173 e inicia sesión como el administrador de arranque. Dos usuarios de demostración (alice@goooy.local / bob@goooy.local, contraseña demo) te permiten enviar correo entre cuentas y ver cómo funciona la entrega local.

Imágenes de contenedor

Compilaciones multietapa, todas ejecutándose sin root (uid 1000) bajo un contexto de seguridad de pod restrictivo:

  • api: Node 22, ejecuta prisma migrate deploy y luego el servidor; expone HTTP (4000) y los puertos de ingesta SMTP/LMTP (2525/2526).
  • web: compilación de Vite servida por nginx; hace de proxy inverso para /api, /ws y las rutas de protocolo, establece cabeceras de seguridad y realiza el respaldo SPA.
  • marketing: un sitio público estático de Astro (opcional; consulta la Guía del administrador).
  • mail: Postfix, Dovecot, Rspamd (solo cuando el servidor de correo está habilitado).

Configuración esencial

La configuración está centralizada y validada con Zod en el arranque. La API falla rápido si falta JWT_SECRET (≥16 caracteres) o DATABASE_URL, o si no son válidos, de modo que un despliegue mal configurado nunca arranca en un estado a medio romper. Todo lo demás tiene valores predeterminados sensatos.

Las variables más importantes:

GrupoVariables clave
NúcleoPUBLIC_WEB_URL, PUBLIC_API_URL, API_PORT (4000)
Autenticación (obligatorio)JWT_SECRET (≥16 caracteres), JWT_ACCESS_TTL (900s), JWT_REFRESH_TTL (30d)
Datos (obligatorio)DATABASE_URL, REDIS_URL
Almacenamiento de objetosS3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY / S3_SECRET_KEY
Correo (saliente)SMTP_HOST / SMTP_PORT / SMTP_SECURE
Correo (entrante)SMTP_INGEST_*, LMTP_INGEST_*, RSPAMD_URL, DOVECOT_LMTP_*
ReunionesMEET_ICE_SERVERS (servidores STUN/TURN en formato JSON)
ArranqueBOOTSTRAP_ORG / BOOTSTRAP_DOMAIN / BOOTSTRAP_ADMIN_EMAIL / BOOTSTRAP_ADMIN_PASSWORD

Secretos. JWT_SECRET y DATABASE_URL deberían provenir de un Secret de Kubernetes que tú proporcionas (secret.existingSecret). Nunca lleves el valor predeterminado del chart a producción. JWT_SECRET cumple una doble función: también sella las claves privadas S/MIME, los secretos de cliente de SSO y las credenciales de migración en reposo, de modo que cambiarlo invalida esos valores sellados. Rótalo de forma deliberada. La tabla completa de variables de entorno está en Despliegue.


Adónde ir después

  • La Guía del administrador cubre la operación de la suite desplegada: la consola de administración, organizaciones y usuarios, la política de autenticación, el servidor de correo, la gestión de dispositivos, la migración, la multitenencia y las copias de seguridad.
  • La Guía del usuario es la visión de cada aplicación desde el punto de vista del usuario final.
  • La referencia técnica completa (arquitectura, modelo de datos, servidor de correo, multitenencia, despliegue, migración y los protocolos de cliente nativo) se distribuye con el código fuente del producto.