Despliegue en Heroku

Vamos a ver cómo subir una aplicación Node.js a Heroku.

Antes de empezar

Estos son los primeros pasos que tenemos que seguir antes de subir el código al servidor:

Heroku deployment

  1. Enlace dinámico de puertos

Heroku nos va a decir qué puerto va a utilizar nuestra aplicación, así que tenemos que asegurarnos de que ese es el puerto en el que estamos escuchando. Para ello, vamos a utilizar las variables de entorno:

# index.js

const PORT = process.env.PORT || 5000;
app.listen(PORT);

Básicamente, lo que quiere decir este código es que, si existe la variable de entorno PORT, utilízala, si no, utiliza el puerto 5000.

  1. Especificar la versión de Node.js utilizada

Tenemos que decirle a Heroku qué versiones de Node.js y npm estamos utilizando en la aplicación. Para ello, añadimos esto en el archivo package.json:

# package.json

...
"engines": {
  "node": "8.11.3",
  "npm": "6.4.1"
},
...
  1. Especificar script de arranque

Además, tenemos que darle a Heroku las instrucciones necesarias para arrancar la aplicación. Para ello, añadimos esto en el archivo package.json:

# package.json

...
"scripts": {
  "start": "node index.js"
},
...
  1. Crear un archivo .gitignore

(Esto probablemente ya lo hayas hecho si ya subiste tu código a un repositorio Git ✅).

Simplemente, nos aseguramos de que las dependencias del proyecto no están siendo rastreadas por Git.

/node_modules

Primer despliegue

Ahora vamos a ver qué es lo que tenemos que hacer la primera vez que vayamos a desplegar la aplicación.

Heroku first time deploy

  1. Crear una cuenta en Heroku

Lo primero que tenemos que hacer es crearnos una cuenta en Heroku.

  1. Crear un repositorio Git

(Una vez más, puede que esto ya lo hayas hecho también ✅).

Si no es el caso, los pasos son estos:

git init
git add .
git commit -m "Initial commit"
  1. Instalar Heroku CLI y crear una nueva aplicación

Instalamos Heroku CLI. Una vez instalado, comprueba que todo haya salido bien mirando la versión instalada:

$ heroku -v
heroku/7.18.3 darwin-x64 node-v10.12.0

Ahora tenemos que loguearnos en Heroku para poder crear una nueva aplicación:

heroku login

Una vez estemos dentro, creamos la aplicación:

$ heroku create
Creating app... done, ⬢ salty-scrubland-60597
https://salty-scrubland-60597.herokuapp.com/ | https://git.heroku.com/salty-scrubland-60597.git

El resultado de ese comando nos va a dar dos URLs. La primera es la URL de nuestra aplicación, y la segunda el repositorio Git donde tenemos que subir el código para desplegar la app.

  1. Desplegar la aplicación con Heroku CLI

Añadimos el repositorio remoto de Heroku a nuestro repositorio local:

git remote add heroku https://git.heroku.com/salty-scrubland-60597.git

Remote Heroku already exists

Si te aparece un mensaje del tipo: fatal: remote heroku already exists, es porque Git ya añadió el repositorio remoto automáticamente cuando metiste el comando heroku create.

Después, hacemos un push de la rama master al repositorio heroku:

git push heroku master

Finalmente, si fuera necesario por si hubiera habido algún error, podemos ver los logs del servidor:

heroku logs

Desplegar la aplicación con GitHub

Aunque ya hemos visto cómo desplegar una aplicación utilizando Heroku CLI, también es posible conectarse con GitHub para que la aplicación se despliegue automáticamente cada vez que hacemos un push a GitHub.

Para ello, tendremos que modificar el Deployment method dentro de los ajustes de nuestra app en Heroku.

Siguientes despliegues

Las próximas veces que quieras desplegar la aplicación, lo único que tendremos que hacer es utilizar el método que hayamos configurado en Heroku (Heroku CLI o GitHub).

Heroku subsequent deploys

Variables de entorno

Otra de las cosas que tenemos que configurar son las variables de entorno que estemos utilizando en nuestro código.

Anteriormente, hemos ido guardando todas estas variables de entorno locales dentro del archivo /config/keys.js, el cual habíamos incluido dentro de .gitignore para no subirlo al servidor.

El archivo /config/keys.js debería tener esta pinta:

module.exports = {
  COOKIE_KEY: ...,

  GOOGLE_CLIENT_ID: ...,
  GOOGLE_CLIENT_SECRET: ...,
  GOOGLE_CLIENT_CALLBACK: ...,

  MONGO_URI: ...,
};

Antes de desplegar el código en Heroku, lo que tenemos que hacer es modificar un poco nuestra forma de recuperar las variables de entorno, según estemos en local o en producción.

En producción, las variables de entorno no van a estar guardadas en un archivo del proyecto, sino que van a configurarse dentro de la aplicación creada en Heroku.

Por tanto, siguiendo el siguiente esquema, vamos a crear dos archivos, /config/dev.js y /config/prod.js, donde manejaremos las variables de entorno de desarrollo y producción, respectivamente, y los llamaremos desde /config/keys.js, que de ahora en adelante simplemente va a encargarse de ver si el código está siendo ejecutado en local o en producción, y en función de esto utilizar el archivo de variables local o las variables configuradas en Heroku.

Variables de entorno en desarrollo y producción

Los archivos dentro de /config quedarían de la siguiente manera:

// /config/keys.js

if (process.env.NODE_ENV === 'production') {
  // We are in production. Return the prod set of keys.
  module.exports = require('./prod');
} else {
  // We are in development. Return the dev set of keys.
  module.exports = require('./dev');
}
// /config/dev.js

module.exports = {
  COOKIE_KEY: ...,

  GOOGLE_CLIENT_ID: ...,
  GOOGLE_CLIENT_SECRET: ...,
  GOOGLE_CLIENT_CALLBACK: ...,

  MONGO_URI: ...,
};
// /config/prod.js

module.exports = {
  COOKIE_KEY: process.env.COOKIE_KEY,

  GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,
  GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,
  GOOGLE_CLIENT_CALLBACK: process.env.GOOGLE_CLIENT_CALLBACK,

  MONGO_URI: process.env.MONGO_URI,
};

.gitignore

El archivo .gitignore quedaría así:

/config/dev.js