Instalar y configurar Node JS para una aplicación en producción sobre Ubuntu 20.04

Instalar y configurar Node JS para una aplicación en producción sobre Ubuntu 20.04

Muchas de las herramientas utilizadas para el desarrollo de aplicaciones incluyen un servidor web de prueba. Esto hace posible que puedas enfocarte inicialmente en escribir código sin tener que preocuparte sobre el despliegue a un ambiente más robusto. Sin embargo, para que el software cumpla su propósito en algún momento necesitarás ponerlo en funcionamiento en algún lugar al que tus usuarios puedan acceder. Por esa razón, en esta guía te explicaremos cómo instalar y configurar Node para una aplicación en producción sobre Ubuntu 20.04.

Requisitos previos

Paso 1: Instalación de Nginx

El servidor web que provee Node para propósitos de desarrollo no es lo suficientemente robusto para un ambiente de producción. Por esa razón, instala Nginx para poder servir la aplicación que vas a escribir posteriormente:

sudo apt update && sudo apt install nginx

Paso 2: Creación de una aplicación de Node

Para empezar, crea un directorio para alojar la aplicación:

mkdir node-app-prod
cd node-app-prod

A continuación, copia el siguiente código (adaptado de la documentación oficial de Node) en un archivo nuevo llamado index.js.

nano index.js
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('Hola mundo!\n');
});
server.listen(port, hostname, () => {
    console.log(`Servidor corriendo en en http://${hostname}:${port}/`);
});

Luego de guardarlo, ejecuta el siguiente comando para ejecutar la aplicación:

node index.js

Como la terminal actual no aceptará comandos mientras la aplicación esté corriendo, abre otra para probarla desde la línea de comandos:

curl http://localhost:3000

En este punto deberías ver lo siguiente en cada terminal:

Si bien hemos verificado el funcionamiento, hay dos razones por las que esta aplicación todavía no está lista para su uso en producción:

  1. El servidor web provisto por Node se mantendrá corriendo, pero solamente hasta que presiones Ctrl + C o cierres la terminal.
  2. Solamente puedes acceder a la aplicación desde adentro del servidor y utilizando la línea de comandos.

En los siguientes pasos aprenderás cómo resolver ambas limitaciones.

Paso 3: Instalación y configuración de PM2

Con el fin de mantener la aplicación corriendo como servicio en segundo plano, necesitas instalar un gestor de aplicaciones de Node. PM2 es uno de los más conocidos y puedes instalarlo de forma global fácilmente. De esta forma, estará disponible para su integración con systemd posteriormente.

npm install pm2@latest -g

Una vez finalizada la instalación, ejecuta la aplicación:

pm2 start index.js

Como resultado, verás información interesante en la lista de procesos de PM2. Esto también hace posible que abras o consultes la aplicación desde la misma terminal:

PM2 identifica a la aplicación con el nombre de archivo sin la extensión .js tal como puedes ver en la columna name. Además, pid muestra el ID del proceso, status el estado de la aplicación, mientras que cpu y mem indican el uso de procesador y memoria RAM, respectivamente.

El gestor de procesos se encargará de levantar la aplicación si ocurre algún problema. Sin embargo, es necesario que systemd esté al tanto para que también la arranque de forma automática luego de reiniciar el sistema. Para hacerlo, utiliza el siguiente comando para obtener el script de inicio que luego deberás correr reemplazando gabriel por tu propio usuario:

pm2 startup systemd
sudo env PATH=$PATH:/home/gabriel/.nvm/versions/node/v14.17.1/bin /home/gabriel/.nvm/versions/node/v14.17.1/lib/node_modules/pm2/bin/pm2 startup systemd -u gabriel --hp /home/gabriel

Al guardar la lista de procesos de PM2, generarás los recursos de systemd que harán posible que arranque la aplicación al reiniciar el sistema bajo tu usuario. En este caso también deberás reemplazar gabriel por tu propia cuenta.

pm2 save
sudo systemctl enable pm2-gabriel
sudo systemctl start pm2-gabriel

Si el último comando genera un error como el que ilustra la imagen, reinicia el sistema con sudo systemctl reboot

Luego verifica el estado del servicio con systemctl status pm2-gabriel:

Tal como se aprecia arriba, entre los detalles también aparece la lista de los procesos que PM2 está ejecutando para tu cuenta. Lo único que resta hacer ahora es servir la aplicación a través de Nginx, utilizándolo como un servidor proxy inverso.

Paso 4: Integración con Nginx

Para comenzar, crea un archivo de configuración para cloudme.fun en /etc/nginx/sites-available/cloudme.fun.conf. Si bien utilizaremos http para ilustrar, te recomendamos luego agregar un certificado tal como explicamos en Cómo asegurar Nginx con Let’s Encrypt en Ubuntu 20.04.

sudo nano /etc/nginx/sites-available/cloudme.fun.conf
server {
     listen 80;
     server_name cloudme.fun;
     location / {
         proxy_pass http://localhost:3000;
         proxy_http_version 1.1;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection 'upgrade';
         proxy_set_header Host $host;
         proxy_cache_bypass $http_upgrade;
     }
 }

Guarda los cambios y revisa la configuración de Nginx antes de reiniciar el servidor web:

sudo nginx -t
sudo systemctl restart nginx

Finalmente, abre el navegador web utilizando el nombre de dominio:

Si no puedes ver un resultado similar, consulta los logs de Nginx en /var/log/nginx para diagnosticar y solucionar cualquier problema que pueda existir.

Conclusión

En esta guía aprendiste cómo ejecutar una aplicación de Node como servicio y a servirla a través de Nginx. Estas dos características, junto con añadir la seguridad que brinda un certificado, te permitirán correr tu desarrollo en un ambiente de producción.

¿Te resultó útil esta guía?

Imagen por defecto
Gabriel Cánepa
Gabriel trabaja actualmente como desarrollador full-stack en Scalar, una firma que se dedica a hacer valuaciones de empresas. Es Administrador de Sistemas certificado por la Fundación Linux y previamente ha escrito un gran número de artículos y contenidos técnicos sobre el tema para: DigitalOcean, Linode, Carrera Linux Argentina y Tecmint. Tiene una certificación en programación de la Universidad de Brigham Young-Idaho, y está completando las carreras de programador y analista de sistemas en la Universidad Nacional de Villa Mercedes (UNViMe). En su tiempo libre, Gabriel disfruta leyendo libros de Stephen R. Covey, tocando piano y guitarra, y enseñando conocimientos de programación a su dos hijas.