DYXO - Home
← Blog
nestjs postgresql ingeniería saas

NestJS + PostgreSQL en producción: lecciones aprendidas construyendo Menú Rapidito

Equipo DYXO · 10 de junio de 2025 · 8 min lectura

Menú Rapidito es nuestro producto insignia: una plataforma de digitalización para la industria gastronómica. Después de varios meses en producción con usuarios reales, tenemos lecciones concretas sobre el stack que elegimos y cómo lo operamos. Esto no es una guía paso a paso, sino un resumen honesto de lo que encontramos en el camino.

El stack

La arquitectura de Menú Rapidito es deliberadamente pragmática. Sin tendencias, sin over-engineering:

  • Backend: NestJS con TypeScript estricto
  • Base de datos: PostgreSQL con TypeORM
  • Contenedores: Docker con imágenes optimizadas para producción
  • Deployment: Dokploy en servidor propio
  • Storage: solución híbrida según el caso de uso
  • Pagos: Stripe
  • Emails transaccionales: plantillas dinámicas con un proveedor dedicado
  • Observabilidad: logging estructurado + monitoreo de errores en tiempo real
  • Seguridad: múltiples capas de protección sobre los endpoints públicos

Correr en servidor propio con Dokploy fue una decisión deliberada. Más control, costos predecibles, sin vendor lock-in. El tradeoff es más responsabilidad operativa, y lo aceptamos desde el día uno.

Lo que funcionó bien

TypeScript estricto sin concesiones

Activar el modo estricto del compilador desde el inicio fue una de las mejores decisiones del proyecto. Obliga a ser explícito sobre los contratos entre capas, lo que reduce drásticamente los bugs en runtime que de otra forma solo aparecen con usuarios reales.

La combinación de TypeScript + NestJS hace que los límites entre módulos sean difíciles de ignorar. Eso es bueno. La fricción que genera en el desarrollo inicial se paga de sobra cuando el proyecto crece.

Arquitectura modular que escala

NestJS impone una estructura que al principio parece verbose pero que escala bien. Cada dominio de negocio vive aislado, con sus propias dependencias y su propio ciclo de vida.

La prueba real: agregar capacidades de inteligencia artificial al producto meses después de lanzar no requirió modificar los módulos existentes. Eso no es suerte, es consecuencia de haber respetado la arquitectura desde el principio.

PostgreSQL para lo que importa

Las transacciones son críticas en cualquier sistema donde el estado debe ser consistente. PostgreSQL las maneja de manera confiable y TypeORM ofrece las herramientas para trabajar con ellas de forma explícita, sin magia que oculte lo que ocurre realmente en la base de datos.

Preferimos saber exactamente qué query se está ejecutando antes que confiar en abstracciones que hacen el trabajo “por nosotros”.

Docker con imágenes livianas

Nuestro proceso de build separa la compilación del artefacto final. La imagen que va a producción no incluye código fuente, dependencias de desarrollo ni herramientas de build. Solo lo estrictamente necesario para correr.

Esto reduce la superficie de ataque, el tiempo de deploy y el tamaño de la imagen de forma significativa.

Lo que nos costó trabajo

El modelo de multi-tenancy

Desde el inicio diseñamos para múltiples operadores en la misma infraestructura, con datos completamente aislados entre sí. Es un problema de diseño que parece simple hasta que empiezas a implementarlo.

La lección más cara del proyecto: el modelo de aislamiento de datos debe definirse antes de escribir la primera entidad. Si se pospone, cada decisión nueva lo complica más. Lo descubrimos tarde.

Las variables de entorno mienten

Una configuración que funciona perfectamente en desarrollo puede comportarse de forma destructiva en producción si una sola variable de entorno está mal definida. Hay comportamientos en el stack que conviene validar explícitamente al arrancar la aplicación, no asumir.

Hoy tenemos validaciones en el arranque que hacen fallar la aplicación rápido y con un mensaje claro, antes de que llegue a hacer algo irreversible.

Observabilidad no viene incluida

En infraestructura propia no tienes dashboards de métricas regalados. Tuvimos que construir nuestro propio stack de observabilidad: logs estructurados en producción, monitoreo de errores en tiempo real, health checks y trazabilidad por request.

Funciona bien. Pero el tiempo que tomó no estaba en el plan inicial. Es uno de esos costos ocultos de no usar una plataforma gestionada.

Decisiones que no cambiaríamos

TypeORM sobre Prisma: más explícito, más cercano al SQL real. Cuando hay problemas en producción, preferimos entender exactamente qué está pasando sin tener que descifrar la abstracción primero.

Dokploy para deployment: gestión de contenedores, variables de entorno, dominios y certificados en nuestro propio servidor. Sin facturas sorpresa a fin de mes.

pnpm como gestor de paquetes: reproducibilidad en instalaciones, mejor manejo del árbol de dependencias y un lockfile que es la fuente de verdad del entorno.

TypeScript strict: el compilador encuentra bugs antes que los usuarios. Sin excepciones, sin any.

Conclusión

No existe un stack perfecto. Existen stacks que conoces bien y stacks que conoces mal. El nuestro nos da estructura para movernos rápido sin perder control sobre lo que ocurre debajo.

Las lecciones más valiosas no son sobre herramientas. Son sobre cuándo tomar las decisiones: el modelo de datos, el aislamiento entre tenants y la estrategia de observabilidad son problemas que duelen en proporción directa al tiempo que se posponen.

Próximamente escribiremos sobre nuestra estrategia de migraciones de base de datos y el flujo de deployment en producción.