Deploy NestJS en Heroku Dyno
Tags: heroku, nestjs, javascript, cloud
Published: 2020-03-29 16:13:53

¡Buenas a todos! En este post vamos a ver como desplegar nuestra aplicación hecha usando [NestJS](https://nestjs.com/) en heroku y con una base de datos MySQL en otro proveedor.

# NestJS

¿Que es NestJS? Es un framework sobre NodeJS que usa TypeScript. Trabaja a través de decoradores, tiene inyección de dependencias «inspirada» en Angular y permite modularizar nuestras aplicaciones.

En resumidas cuentas, es un Framework que, a través de sus herramientas, nos permite un desarrollo más ágil de nuestro backend. Tiene una gran [documentación](https://docs.nestjs.com/) y muchos [ejemplos prácticos.](https://github.com/nestjs/nest/tree/master/sample) 

Si queréis conocer más de él, os recomiendo la charla de [Carlos Caballero](https://dev.to/carlillo) en el DevFest de Málaga, donde explica bastantes conceptos del framework. [Aquí](https://www.youtube.com/watch?v=5dNzU2SqOwk&list=PLKxa4AIfm4pVLH1X6jMju19CKpgVcOh7G&index=20) tenéis el vídeo.

# Heroku

[Heroku](https://dashboard.heroku.com/apps) es una plataforma de cloud computing donde puedes alquilar servidores para poder desplegar tus aplicaciones. Tiene un producto llamado Heroku dyno donde nos provee de instancias gratuitas para el despliegue de aplicaciones con [Buildpacks](https://devcenter.heroku.com/articles/buildpacks). Los cuales tienen una configuración básica por lenguaje para el despliegue de las aplicaciones.

Tenéis toda la información [aquí.](https://www.heroku.com/dynos)

# ¿Porque he usado Heroku?

En mi caso, voy a desplegar un proyecto que no va a producción, es un proyecto académico y por lo tanto me viene mejor que el despliegue sea gratuito.

El "problema" viene cuando quieres desplegar además una base de datos. Heroku tiene **add-ons**, que nos permite desplegar complementos a nuestros servidores. Para desplegar una base de datos SQL tenemos [ClearDB](https://elements.heroku.com/addons/cleardb) que tiene un plan gratuito pero necesita la introducción de una tarjeta de crédito. Por lo que buscando encontré esta [web](https://remotemysql.com/) que nos permite tener varias bases de datos MySQL gratuitas en la nube.

# Manos a la obra

NestJS al estar basado en NodeJS podemos seguir el [tutorial](https://devcenter.heroku.com/articles/getting-started-with-nodejs) de heroku para el despliegue de aplicaciones hechas en NodeJS con algunos cambios que veremos a continuación.

### Desplegar nuestro código

Para subir nuestro código a la instancia que hayamos creado, debemos crear un repositorio local y añadir los cambios de nuestros ficheros. Después de ejecutar el comando 

```bash
$ heroku create
```

Nos habrá creado una rama remota donde podremos subir nuestros cambios al repositorio que ha creado Heroku y el que usará para descargar nuestro código en nuestro servidor.

Un pequeño tip es que podéis elegir el dns que va a usar nuestra aplicación indicando un nombre a continuación de heroku create. Si está libre nos dejará usarlo y si no, nos pedirá que introduzcamos otro. De todas formas este nombre siempre puede ser cambiado.


### Variables de entorno

Debemos conocer que Heroku hará un mapeo de puertos para que nuestra aplicación sea accesible desde el exterior, por lo que no podremos definir de forma estática el puerto por el que escuchará nuestra aplicación. En JS podemos solucionarlo con esta condicional:

```js
const PORT = process.env.PORT || 3000
```

Que nos permitirá mantener nuestro puerto de desarrollo y cogerá dinámicamente el puerto que le asigne Heroku.

Siguiendo con las variables de entorno debemos también configurar nuestra aplicación, que puede ser de forma estática o dinámica.

En el caso de elegir dinámica, por su flexibilidad, disponemos de una instrucción del CLI de Heroku que nos permite añadir variables de entorno a nuestro despliegue, en el caso de utilizar por ejemplo [TypeORM](https://typeorm.io/#/) en nuestro NestJS podriamos definir algo así:

```bash
$ heroku config:set TYPEORM_USERNAME=user TYPEORM_PASSWORD=pass
```

O desde nuestro perfil de administración de nuestro despliegue, en el apartado de Settings > Config Vars.

 
### Procfile

Procfile es el fichero que usa Heroku para conocer que comandos debe ejecutar en el contenedor para iniciar nuestra aplicación. En nuestro caso, con NestJS, en el package.json, contiene la siguiente línea:

```json
"scripts": {
    ...
    "start:prod": "node dist/main",
    ...
  },
```
Que es el que debemos indicar en nuestro Procfile, que es el comando que arrancará nuestro servidor en modo producción.

```
web: npm run start:prod
```

Con esta simple instrucción, Heroku instalará los paquetes necesarios y a continuación ejecutará ese comando para iniciar el servidor. En este fichero podemos indicar cualquier comando o la ejecución de algun fichero.

### Escalamos el servidor

Para publicar nuestro servidor,el CLI de Heroku nos trae el siguiente comando

```bash
$ heroku ps:scale web=1
```

Con el que podremos escalar las instancias de nuestros servidores, en este caso que es gratuita solo podemos escalar a una instancia.

### Conexión con la base de datos

Con los pasos anteriores ya tendremos nuestra aplicación desplegada y accesible, pero nos falta la conexión con la base de datos para que sea totalmente funcional. Para ello vamos a la web de [remotemysql.com](https://remotemysql.com/) y creamos un perfil. Tened en cuenta que necesitamos confirmar el correo.

A continuación, procedemos a crear una base de datos y nos dará credenciales y dirección para que podamos acceder a ella. Esta información deberemos introducirlas en nuestras variables de entorno o estáticamente en la configuración del servidor para que se puedan comunicar.

# Limitaciones

Tanto en la plataforma de Heroku como en la plataforma de mysql remote tienen algunas limitaciones que debemos tener en cuenta:

- En heroku, después de 30 minutos de inactividad, nuestra aplicación entrará en modo reposo y será activada cuando haya una nueva petición. En aplicaciones pesadas, el tiempo de carga de nuevo del servidor puede ser desesperante.

- Solo 2 procesos por instancia en Heroku Dyno.

- RemoteMysql solo permite un tamaño máximo de 5 MB por lo que puede ser muy corto dependiendo del contexto de la aplicación

- Ninguna configuración en el servidor tanto de Heroku como de RemoteMysql

# Ventajas

Como gran ventaja, esta combinación de servicios nos puede proporcionar un despliegue de una aplicación no profesional de forma gratuita y usable sin la necesidad de gestión de servidores o configuración de dominios.

# Resumen

Como resumen global, diría que estas dos plataformas nos dan una gran oportunidad para que aplicaciones normalmente probadas y desarrolladas en local puedan ser accesible por más personas y compartidas de una forma mucho más sencilla. Es una gran opción para proyectos de aprendizaje y proyectos que estén empezando.

¡Un saludo a todos y nos vemos en la próxima!