Migraciones con TimeORM en Producción: Configuración y Ejecución

Clase 21 de 22Curso de NestJS: Autenticación con Passport y JWT

Contenido del curso

Resumen

Llevar una aplicación NestJS con TypeORM a producción implica resolver un problema frecuente: ¿cómo ejecutar migraciones en un entorno donde las variables de ambiente y las dependencias funcionan de forma diferente? Aquí se aborda paso a paso la configuración necesaria para que el CLI de TypeORM se conecte correctamente a la base de datos en Heroku, desde la creación del archivo de configuración hasta la ejecución exitosa de migraciones y la validación de endpoints protegidos.

¿Por qué TypeORM necesita una configuración especial para producción?

TypeORM mantiene tres conexiones posibles en un proyecto típico: la del módulo de la aplicación, una conexión nativa con el driver oficial y la que utiliza el CLI para ejecutar migraciones. En desarrollo, la configuración suele darse mediante variables de ambiente individuales como host, puerto y contraseña. Sin embargo, en producción la conexión llega en una sola variable llamada DATABASE_URL [01:01].

El problema es que no se puede simplemente asignar una variable de ambiente a otra dentro del archivo .env. Por eso, TypeORM ofrece la posibilidad de usar un archivo JavaScript llamado ormconfig.js, donde se puede acceder de forma programática a process.env.DATABASE_URL y pasarla como la URL de conexión [02:27].

¿Cómo se estructura el archivo ormconfig.js?

El archivo exporta un objeto con la configuración de conexión. Lo esencial es indicar el tipo de base de datos (en este caso postgres), y asignar la URL directamente desde la variable de entorno [03:07]:

javascript module.exports = { type: 'postgres', url: process.env.DATABASE_URL, synchronize: false, logging: false, entities: ['src/**/.entity.ts'], migrations: ['src/database/migrations/.ts'], cli: { migrationsDir: 'src/database/migrations', }, };

  • synchronize debe estar en false para evitar cambios automáticos en el esquema.
  • logging puede activarse con una variable de ambiente si se necesita depurar.
  • Las rutas de entities y migrations se definen en formato de array.
  • La propiedad cli.migrationsDir indica dónde se generan las migraciones.

Una vez creado este archivo, las variables individuales de conexión en el .env deben comentarse para evitar conflictos [04:55].

¿Qué errores comunes aparecen al correr migraciones en Heroku?

El primer intento de ejecutar heroku run npm run migrations:run suele fallar porque ts-node no se encuentra en el entorno productivo [06:25]. Esto ocurre porque ts-node está listado como dependencia de desarrollo. Heroku instala las devDependencies solo durante el build y luego las elimina.

La solución es mover tanto ts-node como typescript a las dependencias de producción, ya que las migraciones están escritas en TypeScript y necesitan ser interpretadas [07:15].

¿Cómo conviven dos configuraciones de TypeORM?

Para desarrollo se mantiene la configuración original que usa ts-node directamente. Para producción se crea una configuración paralela que ejecuta con Node [08:00]:

{ "typeorm:prod": "node --require ts-node/register ./node_modules/typeorm/cli.js", "migrations:prod": "npm run typeorm:prod -- migration:run" }

  • El comando migrations:prod utiliza la configuración typeorm:prod.
  • El comando de drop no se habilita en producción por seguridad.
  • Es explícito en su nombre para evitar confusiones con los comandos de desarrollo.

El segundo error frecuente es la falta de configuración SSL [09:48]. Heroku requiere una propiedad ssl en la conexión. Al agregarla en ormconfig.js con ssl: { rejectUnauthorized: false }, la conexión se establece correctamente.

¿Cómo validar que todo funciona en el entorno productivo?

Una vez ejecutadas las migraciones con éxito [10:55], se pueden probar los endpoints directamente. En este caso se crearon marcas, categorías y usuarios utilizando endpoints sin protección, y luego se validó la autenticación con JWT [12:10]:

  • Un administrador puede crear productos tras autenticarse y obtener un token.
  • Un cliente recibe un error de rol al intentar crear productos.
  • Un token alterado devuelve error de autorización.
  • El endpoint público de obtener productos funciona sin token [14:02].

Heroku proporciona una instancia de Postgres con plan gratuito para desarrollo. Para datos productivos reales, es recomendable evaluar planes con backups y mayor estabilidad [14:35].

Una mejora importante es automatizar la ejecución de migraciones con integración continua. Cada vez que se hace push a master, un pipeline puede verificar si hay migraciones pendientes y ejecutarlas automáticamente, ya que TypeORM mantiene una tabla interna que registra qué migraciones se han corrido [15:05]. Heroku ofrece herramientas para configurar este flujo, aunque también es válido mantener el control manual si se prefiere mayor supervisión sobre cada release.

      Migraciones con TimeORM en Producción: Configuración y Ejecución