Saltar al contenido principal

Variables de entorno

Nunca versionar secretos

Los archivos .env no se suben al repositorio. Solo se versionan los .env.example con valores de ejemplo. En producción los valores se cargan en Environment de Dokploy.

ganadero-api​

Resumen para Dokploy​

TipoVariables
ObligatoriasDATABASE_URL, JWT_ACCESS_SECRET, WEB_ORIGIN
Opcionales (tienen valor por defecto)WEB_URL, MAIL_DRIVER (console), MAIL_FROM, SMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_USER, SMTP_PASSWORD, TRUST_PROXY_HOPS (1), LOG_LEVEL, PORT, JWT_ACCESS_TTL_SECONDS, REFRESH_TTL_DAYS, COOKIE_SAMESITE, AUTH_RATE_LIMIT_MAX, AUTH_RATE_LIMIT_WINDOW_SECONDS, INVITATIONS_PER_HOUR, INVITATIONS_PER_DAY, INVITATIONS_NEW_ORG_LIMIT, SESSION_CACHE_TTL_SECONDS, COSTING_WORKER_CONCURRENCY, ENGINE_WORKERS, ENGINE_TIMEOUT_SECONDS, SWAGGER_ENABLED, IMAGE_TAG
Solo en la opción avanzada de dos rolesDATABASE_MIGRATION_URL
Ya no se usan en producciónPOSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, APP_DB_PASSWORD

Base de datos y arranque​

VariableDescripción
NODE_ENV, PORT, LOG_LEVELEntorno, puerto (3000 por defecto) y nivel de log.
DATABASE_URLÚnica conexión en producción, compartida por migrate y la API: la del usuario que creó la base en Dokploy, postgres://<usuario>:<clave>@<nombre-interno-del-postgres>:5432/<base>. No requiere SQL manual: migrate crea el rol sin privilegios ganadero_app y la API ejecuta cada transacción como ese rol (ver Despliegue con Dokploy). Caracteres especiales del usuario o la clave codificados (@ → %40, : → %3A, / → %2F). Obligatoria.
DATABASE_MIGRATION_URLOpcional: solo en desarrollo y en la opción avanzada de dos roles. Conexión del dueño de la base para migrate mientras la API usa ganadero_app. Vacía o ausente: migrate usa DATABASE_URL.
DATABASE_SEED_URLSolo en desarrollo: superusuario local para pnpm db:seed. Nunca en producción.
IMAGE_TAGEtiqueta de la imagen. La API no publica ningún puerto en el host: Traefik la alcanza por la red dokploy-network.

Sesión y seguridad​

VariableDescripción
JWT_ACCESS_SECRETSecreto de los tokens de acceso (mínimo 32 caracteres). Obligatoria. Genere uno propio: openssl rand -base64 48.
JWT_ACCESS_TTL_SECONDSVigencia del token de acceso (900 s por defecto).
REFRESH_TTL_DAYSVigencia del token de refresco (30 días por defecto).
COOKIE_SECURE, COOKIE_SAMESITEAtributos de la cookie de sesión. En producción COOKIE_SECURE es siempre true.
WEB_ORIGINOrigen permitido del frontend (CORS con credenciales). Obligatoria.
AUTH_RATE_LIMIT_MAX, AUTH_RATE_LIMIT_WINDOW_SECONDSLímite de peticiones a /auth/* por IP (10 por 60 s por defecto).
TRUST_PROXY_HOPSCuántos proxies hay delante de la API (0 en local; 1 detrás de Traefik, valor por defecto del Compose de producción).
SESSION_CACHE_TTL_SECONDSSegundos (0 a 30, por defecto 30) del caché en memoria con que se contrasta el token con los permisos vigentes. 0 desactiva el caché. Con varias réplicas, un cambio de rol puede tardar hasta este valor en verse en las otras réplicas.
SWAGGER_ENABLEDHabilita la documentación OpenAPI (/docs). Se recomienda desactivarla en producción.

Correo (invitaciones y restablecimiento de contraseña)​

VariableDescripción
MAIL_DRIVERconsole (valor por defecto) o smtp. Con console la API arranca igual y registra el aviso correos deshabilitados (MAIL_DRIVER=console): en desarrollo el mensaje se ve en el log, pero en producción nunca se registra el cuerpo, así que nadie recibe el enlace. Para enviar correos de verdad use smtp.
MAIL_FROMRemitente, p. ej. Software Ganadero <no-reply@tudominio.com>. Obligatoria con smtp.
SMTP_HOST, SMTP_PORTServidor SMTP (SMTP_HOST obligatoria con smtp; puerto típico 587).
SMTP_USER, SMTP_PASSWORDCredenciales; deben definirse juntas.
SMTP_SECURETLS implícito. Por defecto solo en el puerto 465 (el 587 usa STARTTLS).
WEB_URLBase de los enlaces de los correos. Por defecto, WEB_ORIGIN. Puede incluir un subpath.

Cuotas de invitaciones (anti-relay)​

Por organización; superarlas responde 429. Revocar o reinvitar no devuelve cupo.

VariableDefectoEfecto
INVITATIONS_PER_HOUR20Ventana deslizante de 1 hora.
INVITATIONS_PER_DAY100Ventana deslizante de 24 horas.
INVITATIONS_NEW_ORG_LIMIT5Tope total mientras la organización tenga menos de 24 horas.

ganadero-web​

La imagen es la misma para todos los entornos; estas variables se inyectan al arrancar el contenedor.

VariableDescripción
API_URLURL base de la API (obligatoria en producción), p. ej. https://api.midominio.com/api. Confirme con su enrutamiento si lleva o no un prefijo (la API publica sus rutas en la raíz).
MANUALES_URLURL de este manual (opcional). Si se define, la aplicación descarga las plantillas desde <MANUALES_URL>/plantillas/.
CSP_MODOenforce (por defecto) o report-only.
CSP_REPORT_URIColector de informes CSP (vacío = sin informes).
CSP_CONNECT_SRC_EXTRAOrígenes adicionales permitidos para conexiones, separados por espacio.

manual-ganadero​

VariableDescripción
MANUAL_AUTH_ENABLEDtrue protege el manual con HTTP Basic Auth de nginx.
MANUAL_AUTH_USER, MANUAL_AUTH_PASSWORDCredenciales de ese acceso, obligatorias si está activo (si faltan, el contenedor no arranca; el usuario no puede contener :). Definirlas solo en el entorno de despliegue.
Seguridad

La validación ocurre en nginx, del lado del servidor: la clave se guarda como hash en /etc/nginx/.htpasswd y nunca se envía al navegador. Basic Auth transmite las credenciales en cada petición, así que el dominio debe servirse siempre por HTTPS (Traefik en Dokploy lo gestiona con Let's Encrypt).