Entornos (pre / prod)
Principio
Un entorno = una copia corriendo completa del stack (frontend + backend + base de datos, apuntando a su propio ajolote). Es el mismo código/imagen desplegado dos veces, cada deploy con sus propias variables. No es un proceso compartido cambiando de DB: un proceso solo pertenece a un entorno, porque MikroORM se conecta a una sola DB al forRoot y el backend valida el token contra un solo ajolote (AUTH_SERVICE_URL fijo al boot).
PROD: pupo-panel.pages.dev → pupo.anfibia.io → db "id" → ajolote prod (público)
PRE: dev.pupo-panel.pages.dev → pupo-pre.anfibia.io → db "pupo_pre" → ajolote dev (Tailscale)
Ramas → entorno
Cada servicio (back en Dokploy, front en Cloudflare Pages) trackea una rama y el push dispara el build de ese entorno:
| Rama | Entorno |
|---|---|
dev | Pre |
master | Producción |
Flujo: features → dev (deploya pre) → validar → promover a master (deploya prod). auth-panel y auth-panel-front son repos separados; usar los mismos nombres de rama en ambos.
Base de datos
Ambos entornos comparten la misma instancia de PostgreSQL (en Dokploy), con una base de datos distinta por entorno:
| Var | Prod | Pre |
|---|---|---|
DB_NAME | id | pupo_pre |
DB_USER | anfibio | anfibio |
DB_HOST | databases-postgresqldb-rw2aop (host interno de Dokploy) | igual |
DB_PORT | 5432 | igual |
DB_SSL | false (red interna) | igual |
La base de pre se creó a mano dentro de la misma instancia (conectado como el superusuario anfibio):
CREATE DATABASE pupo_pre;
Al ser anfibio el creador, queda como dueño y las migraciones crean solas los schemas app / configuration en el primer deploy (migration:up corre en el entrypoint).
:::warning Trade-off
Se comparte el superusuario anfibio en ambos entornos, así que la separación es solo lógica (distinto DB_NAME), no a nivel credenciales. Si en el servicio de pre se pone DB_NAME=id por error, pega contra prod. Revisar bien el DB_NAME. Como blindaje futuro se puede dar a cada entorno un usuario dedicado con permisos solo sobre su base.
:::
Fail-fast de configuración
mikro-orm.config.ts falla al arrancar si en producción (NODE_ENV=production) falta DB_NAME/DB_HOST/DB_USER/DB_PASSWORD, en lugar de caer a un fallback silencioso (enterprise_db/user/password) que podía conectar a la base equivocada. En dev se mantienen los defaults locales.
Redis
Ambos entornos comparten la misma instancia de Redis, aislados por índice de base lógica (REDIS_DB):
| Var | Prod | Pre |
|---|---|---|
REDIS_DB | 0 | 1 |
buildRedisUrl() (cache.module.ts) agrega /${REDIS_DB} a la URL. Redis solo se usa como cache (las sesiones viven en ajolote), así que compartir instancia con índices distintos alcanza.
Matriz de variables por entorno
Variables que cambian entre pre y prod:
| Variable | Nota |
|---|---|
DB_NAME | pupo_pre vs id |
REDIS_DB | 1 (pre) vs 0 (prod) |
AUTH_SERVICE_URL | ajolote de pre (Tailscale) vs ajolote de prod (público) |
AJOLOTE_SERVICE_KEY | debe matchear TENANT_SYNC_SERVICE_KEY del ajolote del entorno |
ENABLE_AUTH_PROXY | true en pre, off en prod (ver Autenticación) |
FRONT_URL / CORS_ORIGIN | dominio del front del entorno |
NEW_RELIC_APP_NAME | Pupo-pre vs Pupo (o NEW_RELIC_ENABLED=false en pre) |
Iguales en ambos: DB_HOST, DB_PORT, DB_USER, DB_SSL, AUTH_APP_ID=pupo, NODE_ENV=production.