Configuración de Conexiones a Base de Datos en Heroku y Entorno Local

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

Contenido del curso

Resumen

Cuando desplegamos una aplicación en Heroku con una base de datos Postgres, la forma de conectarse cambia por completo. Ya no recibiremos variables separadas como host, puerto, usuario o contraseña, sino una única variable de entorno llamada DATABASE_URL que contiene toda la cadena de conexión. Adaptar nuestro proyecto a este formato es fundamental para que funcione tanto en desarrollo local como en producción sin romper nada.

¿Por qué Heroku envía una sola variable de entorno para la conexión?

Heroku administra sus bases de datos de forma automática y proporciona una variable llamada DATABASE_URL [0:41] que incluye protocolo, usuario, contraseña, host, puerto y nombre de la base de datos en un solo string. El formato sigue esta estructura:

postgres://usuario:password@host:puerto/nombre_base_datos

Esto significa que debemos estandarizar nuestra configuración local para usar el mismo formato. En lugar de mantener variables separadas como DB_HOST, DB_PORT, DB_USER y DB_PASSWORD, creamos una sola variable DATABASE_URL en nuestro archivo de entorno con los datos locales [1:30]:

DATABASE_URL=postgres://root:123@localhost:5432/mydb

De esta manera, tanto en desarrollo como en producción, la aplicación lee la misma variable de ambiente y la lógica de conexión se simplifica enormemente.

¿Cómo adaptar el módulo de base de datos en NestJS?

El módulo de base de datos del proyecto leía cada variable por separado desde el objeto config. Ahora solo necesitamos leer postgres_url [2:28]. Los cambios principales son:

  • Crear una variable postgres_url que reciba el valor de DATABASE_URL.
  • En la configuración de TypeORM, reemplazar las propiedades individuales (host, port, username, database) por la propiedad url y asignarle directamente la cadena de conexión [3:08].
  • Agregar la configuración de SSL que Heroku exige, estableciendo rejectUnauthorized en false [3:35].

Para la conexión con el driver nativo usando Client de pg, el cambio es similar: en lugar de pasar cada parámetro, se utiliza connectionString apuntando a postgres_url [3:55] y se replica la misma configuración SSL.

typescript // Configuración TypeORM { type: 'postgres', url: configService.get('postgres_url'), ssl: { rejectUnauthorized: false, }, }

// Conexión nativa con pg const client = new Client({ connectionString: postgres_url, ssl: { rejectUnauthorized: false }, });

¿Qué pasa con las validaciones en el app module?

En el AppModule se validaban las variables de entorno una a una. Ahora debemos remover las validaciones del puerto de base de datos, host y demás variables individuales, y en su lugar validar únicamente que DATABASE_URL llegue correctamente [5:12]. Esto asegura que Heroku provea la conexión antes de iniciar la aplicación.

¿Qué variables de entorno necesitamos configurar en Heroku?

Desde la interfaz web de Heroku, en la sección de settings, configuramos las variables necesarias [5:50]:

  • DATABASE_URL: Heroku la proporciona automáticamente al agregar el addon de Postgres.
  • DATABASE_NAME: si tu aplicación la utiliza internamente.
  • PORT: Heroku la asigna dinámicamente.
  • API_KEY: para autenticación de la API.
  • JWT_SECRET: la llave secreta para firmar tokens, que solo el equipo de infraestructura debería conocer [6:15].

¿Cómo hacer deployment a Heroku desde la terminal?

Cuando creamos el proyecto en Heroku, se agregó un remote adicional a Git. Mientras origin apunta a GitHub, heroku apunta directamente a los servidores de Heroku [6:40]. El proceso de despliegue sigue estos pasos:

  • Guardar cambios y hacer commit en la rama de trabajo.
  • Cambiar a la rama master con git checkout master.
  • Hacer merge de la rama de desarrollo.
  • Ejecutar git push heroku master [7:05].

Una vez completado el push, la aplicación queda disponible en la URL asignada. Al acceder a /docs, la documentación autogenerada con Swagger se muestra correctamente [7:25].

¿Por qué aparece el error "relation products does not exist"?

Al consultar el endpoint de productos, Heroku devuelve un error porque las tablas no existen en la base de datos remota [7:40]. Revisando los logs con heroku logs --tail [7:52], el mensaje confirma que la relación products no se encuentra. Esto ocurre porque el proyecto utiliza un sistema de migraciones y estas aún no se han ejecutado en el entorno productivo.

La base de datos está conectada y funcionando, pero las migraciones que crean las tablas todavía deben correrse en la instancia de Heroku. ¿Has tenido que adaptar cadenas de conexión similares en tus proyectos? Comparte tu experiencia y cómo resolviste los desafíos de configuración en producción.