Cómo configurar una aplicación Node.js para producción en Ubuntu 16.04

Introducción
Node.js es un entorno de ejecución de código abierto de JavaScript para crear aplicaciones de red y del lado del servidor. La plataforma funciona en Linux, MacOS, FreeBSD y Windows. Las aplicaciones de Node.js se pueden ejecutar en la línea de comandos, pero nos centraremos en ejecutarlas como un servicio, de modo que se reinicien automáticamente al reiniciar o fallar el sistema y se puedan usar de forma segura en un entorno de producción.
En este tutorial, explicaremos cómo configurar un entorno Node.js listo para producción en un único servidor Ubuntu 16.04. Este servidor ejecutará una aplicación Node.js administrada por PM2 y brindará a los usuarios acceso seguro a la aplicación a través de un proxy inverso Nginx. El servidor Nginx ofrecerá HTTPS, utilizando un certificado gratuito proporcionado por Let’s Encrypt.
Prerrequisitos
Esta guía asume que usted tiene lo siguiente:
- Un servidor Ubuntu 16.04, configurado con un usuario no root con
sudo
privilegios, como se describe en la guía de configuración inicial del servidor para Ubuntu 16.04 . - Un nombre de dominio que apunta a la IP pública de su servidor, según Cómo configurar un nombre de host con DigitalOcean . En este tutorial se utilizará example.com .
- Nginx instalado, explicado en Cómo instalar Nginx en Ubuntu 16.04
- Nginx configurado con SSL mediante certificados Let’s Encrypt. Cómo proteger Nginx con Let’s Encrypt en Ubuntu 16.04 lo guiará a través del proceso.
Cuando haya completado los requisitos previos, tendrá un servidor que servirá la página de marcador de posición Nginx predeterminada en https://ejemplo.com/ .
Comencemos instalando el entorno de ejecución Node.js en su servidor.
Paso 1: Instalación de Node.js
Instalaremos la última versión LTS de Node.js, utilizando los archivos de paquetes NodeSource .
Primero, debes instalar el PPA de NodeSource para poder acceder a su contenido. Asegúrate de estar en tu directorio de inicio y usa curl
para recuperar el script de instalación de los archivos de Node.js 16.x:
- cd ~
- curl -sL https://deb.nodesource.com/setup_16.x -o nodesource_setup.sh
Puede inspeccionar el contenido de este script con nano
(o con su editor de texto preferido):
- nano nodesource_setup.sh
A continuación ejecute el script en sudo
:
- sudo bash nodesource_setup.sh
El PPA se agregará a su configuración y su caché de paquetes local se actualizará automáticamente. Después de ejecutar el script de configuración desde nodesource, puede instalar el paquete Node.js de la misma manera que lo hizo anteriormente:
- sudo apt-get install nodejs
El nodejs
paquete contiene el node
binario y el npm
, por lo que no es necesario instalarlo npm
por separado. Sin embargo, para que algunos npm
paquetes funcionen (como aquellos que requieren compilar el código fuente), deberá instalar el build-essential
paquete:
- sudo apt-get install build-essential
El entorno de ejecución de Node.js ya está instalado y listo para ejecutar una aplicación. Escribamos una aplicación de Node.js.
Paso 2: Creación de una aplicación Node.js
Escribiremos una aplicación que diga “Hola mundo” y que devuelva “Hola mundo” a cualquier solicitud HTTP. Esta es una aplicación de muestra que te ayudará a configurar Node.js y que puedes reemplazar con tu propia aplicación. Solo asegúrate de modificar tu aplicación para que escuche en las direcciones IP y puertos adecuados.
Hola código mundial
Primero, crea y abre tu aplicación Node.js para editarla. Para este tutorial, usaremos nano
una aplicación de muestra llamada hello.js
:
- cd ~
- nano hello.js
Inserte el siguiente código en el archivo. Si lo desea, puede reemplazar el puerto resaltado, 8080
, en ambas ubicaciones (asegúrese de utilizar un puerto que no sea de administrador, es decir, 1024 o superior):
hola.js
#!/usr/bin/env nodejsvar http = require('http');http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Worldn');}).listen(8080, 'localhost');console.log('Server running at http://localhost:8080/');
Ahora guarde y salga.
Esta aplicación Node.js escucha en la dirección ( localhost
) y el puerto ( 8080
) especificados, y devuelve “Hola mundo” con un 200
código HTTP de éxito. Dado que estamos escuchando en localhost , los clientes remotos no podrán conectarse a nuestra aplicación.
Solicitud de prueba
Para probar su aplicación, configúrela hello.js
para que sea ejecutable mediante chmod
:
- chmod +x ./hello.js
Luego ejecútalo así:
- ./hello.js
OutputServer running at http://localhost:8080/
Nota: ejecutar una aplicación Node.js de esta manera bloqueará comandos adicionales hasta que se cierre la aplicación presionando Ctrl-C .
Para probar la aplicación, abra otra sesión de terminal en su servidor y conéctese al host local con curl
:
- curl http://localhost:8080
Si ve el siguiente resultado, la aplicación está funcionando correctamente y escuchando en la dirección y el puerto adecuados:
OutputHello World
Si no ve el resultado adecuado, asegúrese de que su aplicación Node.js esté ejecutándose y configurada para escuchar en la dirección y el puerto adecuados.
Una vez que esté seguro de que funciona, vuelva a su otra terminal y elimine la aplicación Node.js (si aún no lo ha hecho) presionando Ctrl+C .
Paso 3: Instalación de PM2
Ahora instalaremos PM2, que es un administrador de procesos para aplicaciones Node.js. PM2 ofrece una manera sencilla de administrar y convertir aplicaciones en daemon (ejecutarlas en segundo plano como un servicio).
Usaremos npm
, un administrador de paquetes para módulos de Node que se instala con Node.js, para instalar PM2 en nuestro servidor. Use este comando para instalar PM2:
- sudo npm install -g pm2
La -g
opción indica npm
que se debe instalar el módulo globalmente , para que esté disponible en todo el sistema.
Paso 4: Gestión de aplicaciones con PM2
Cubriremos algunos usos básicos de PM2.
Iniciar aplicación
Lo primero que querrás hacer es usar el pm2 start
comando para ejecutar tu aplicación, hello.js
, en segundo plano:
- pm2 start hello.js
Esto también agrega su aplicación a la lista de procesos de PM2, que se genera cada vez que inicia una aplicación:
Output[PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2[PM2] PM2 Successfully daemonized[PM2] Starting /home/sammy/hello.js in fork_mode (1 instance)[PM2] Done.┌─────┬──────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │├─────┼──────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤│ 0 │ hello │ default │ N/A │ fork │ 13734 │ 0s │ 0 │ online │ 0% │ 25.0mb │ sammy │ disabled │└─────┴──────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
Como puede ver, PM2 asigna automáticamente un nombre (basado en el nombre del archivo, sin la .js
extensión) y un ID de PM2 . PM2 también mantiene otra información, como el PID del proceso, su estado actual y el uso de memoria.
Las aplicaciones que se ejecutan en PM2 se reiniciarán automáticamente si fallan o se cierran, pero es necesario realizar un paso adicional para que la aplicación se inicie al iniciar el sistema (arranque o reinicio). Afortunadamente, PM2 ofrece una forma sencilla de hacerlo: el startup
subcomando.
El startup
subcomando genera y configura un script de inicio para iniciar PM2 y sus procesos administrados en los arranques del servidor:
- pm2 startup systemd
La última línea de la salida resultante incluirá un comando que deberá ejecutar con privilegios de superusuario:
Output[PM2] Init System found: systemd[PM2] You have to run this command as root. Execute the following command:sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
Ejecute el comando que se generó (similar al resultado resaltado arriba, pero con su nombre de usuario en lugar de sammy
) para configurar PM2 para que se inicie en el arranque (use el comando de su propio resultado):
- sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
Esto creará una unidad systemd que se ejecuta pm2
para su usuario en el arranque. Esta pm2
instancia, a su vez, ejecuta hello.js
. Puede comprobar el estado de la unidad systemd con systemctl
:
- systemctl status pm2-sammy
Para obtener una descripción detallada de systemd, consulte Conceptos básicos de Systemd: trabajar con servicios, unidades y el diario .
Otros usos de PM2 (opcional)
PM2 ofrece muchos subcomandos que le permiten administrar o buscar información sobre sus aplicaciones. Tenga en cuenta que si se ejecuta pm2
sin argumentos, se mostrará una página de ayuda, que incluye ejemplos de uso, que cubren el uso de PM2 con más detalle que esta sección del tutorial.
Detenga una aplicación con este comando (especifique PM2 App name
o id
):
- pm2 stop app_name_or_id
Reinicie una aplicación con este comando (especifique PM2 App name
o id
):
- pm2 restart app_name_or_id
La lista de aplicaciones administradas actualmente por PM2 también se puede consultar con el list
subcomando:
- pm2 list
Se puede encontrar más información sobre una aplicación específica utilizando el info
subcomando (especifique el nombre o el ID de la aplicación PM2 ):
- pm2 info example
El monitor de procesos PM2 se puede abrir con el monit
subcomando. Esto muestra el estado de la aplicación, la CPU y el uso de la memoria:
- pm2 monit
Ahora que su aplicación Node.js está ejecutándose y administrada por PM2, configuremos el proxy inverso.
Paso 5: Configuración de Nginx como servidor proxy inverso
Ahora que su aplicación está ejecutándose y escuchando en localhost , debe configurar una forma para que sus usuarios puedan acceder a ella. Configuraremos el servidor web Nginx como un proxy inverso para este propósito.
En el tutorial de requisitos previos, configuramos nuestra configuración de Nginx en el /etc/nginx/sites-available/default
archivo. Abra el archivo para editarlo:
- sudo nano /etc/nginx/sites-available/default
Dentro del server
bloque debería haber un location /
bloque existente. Reemplace el contenido de ese bloque con la siguiente configuración. Si su aplicación está configurada para escuchar en un puerto diferente, actualice la parte resaltada al número de puerto correcto.
/etc/nginx/sites-available/predeterminado
. . . location / { proxy_pass http://localhost:8080; 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; }}
Esto configura el servidor para que responda a las solicitudes en su raíz. Suponiendo que nuestro servidor está disponible en example.com
, el acceso https://example.com/
a través de un navegador web enviaría la solicitud a hello.js
, que escucha en el puerto 8080
en localhost .
Puedes agregar location
bloques adicionales al mismo bloque de servidor para brindar acceso a otras aplicaciones en el mismo servidor. Por ejemplo, si también estuvieras ejecutando otra aplicación Node.js en el puerto 8081
, podrías agregar este bloque de ubicación para permitir el acceso a ella mediante http://example.com/app2
:
/etc/nginx/sites-available/default — Opcional
location /app2 { proxy_pass http://localhost:8081; 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; }
Una vez que haya terminado de agregar los bloques de ubicación para sus aplicaciones, guarde y salga.
Asegúrate de no haber introducido ningún error de sintaxis al escribir:
- sudo nginx -t
A continuación, reinicie Nginx:
- sudo systemctl restart nginx
Suponiendo que su aplicación Node.js se está ejecutando y que las configuraciones de su aplicación y Nginx son correctas, ahora debería poder acceder a su aplicación a través del proxy inverso de Nginx. Pruébelo accediendo a la URL de su servidor (su dirección IP pública o nombre de dominio).
Conclusión
¡Felicitaciones! Ahora tienes tu aplicación Node.js ejecutándose detrás de un proxy inverso Nginx en un servidor Ubuntu 16.04. Esta configuración de proxy inverso es lo suficientemente flexible como para brindar a tus usuarios acceso a otras aplicaciones o contenido web estático que quieras compartir. Buena suerte con tu desarrollo con Node.js.
Deja una respuesta