Node.js es una plataforma potente para ejecutar aplicaciones JavaScript del lado del servidor. Cuando se despliega una aplicación Node.js en la nube, es esencial configurarla de manera que sea robusta, escalable y confiable. En esta guía, exploraremos el proceso para configurar un servidor Node.js en un entorno en la nube utilizando dos herramientas importantes: Nginx y PM2. Con Nginx como servidor proxy inverso y PM2 como administrador de procesos, se logrará un entorno estable, eficiente y de alto rendimiento.
Requisitos previos
Antes de empezar, es necesario contar con:
- Un servidor remoto o instancia en la nube con acceso root.
- Node.js y NPM instalados.
- Conocimientos básicos de la línea de comandos.
- Acceso SSH para gestionar el servidor remoto.
A continuación, te guiamos en los pasos necesarios para lograr una configuración completa y funcional.
Paso 1: Acceso al servidor y actualización de paquetes
Primero, inicia sesión en tu servidor mediante SSH:
bash
Copiar código
ssh usuario@direccion-ip-del-servidor
Actualiza los paquetes del sistema para asegurarte de que todo esté al día:
bash
Copiar código
sudo apt update && sudo apt upgrade -y
Paso 2: Instalación de Node.js y NPM
Node.js y NPM se pueden instalar fácilmente en la mayoría de los servidores usando los repositorios de NodeSource. Para asegurarte de instalar la última versión, ejecuta los siguientes comandos:
- Agrega el repositorio de NodeSource:
bash
Copiar código
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash –
- Instala Node.js y NPM:
bash
Copiar código
sudo apt install -y nodejs
Para verificar que la instalación fue exitosa, ejecuta:
bash
Copiar código
node -v
npm -v
Paso 3: Crear una aplicación Node.js básica
Antes de configurar Nginx y PM2, es útil contar con una aplicación básica de Node.js para probar. Vamos a crear una aplicación sencilla que responderá con un mensaje “Hello, World!” en el puerto 3000.
- Crea un directorio para tu proyecto y navega a él:
bash
Copiar código
mkdir mi-app-node && cd mi-app-node
2. Inicializa un proyecto Node.js:
bash
Copiar código
npm init -y
3. Crea un archivo app.js con el siguiente contenido:
javascript
Copiar código
const express = require(‘express’);
const app = express();
const PORT = 3000;
app.get(‘/’, (req, res) => {
res.send(‘Hello, World!’);
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
4. Instala el paquete Express:
bash
Copiar código
npm install express
5. Prueba la aplicación ejecutándola:
bash
Copiar código
node app.js
Si visitas http://localhost:3000 desde el servidor, deberías ver el mensaje “Hello, World!”.
Paso 4: Instalar y Configurar PM2
PM2 es una herramienta poderosa que nos ayuda a gestionar las aplicaciones Node.js, permitiendo ejecutarlas en segundo plano, gestionarlas como servicios y garantizar que se reinicien automáticamente en caso de fallos.
- Instala PM2 globalmente:
bash
Copiar código
sudo npm install -g pm2
- Inicia tu aplicación usando PM2:
bash
Copiar código
pm2 start app.js –name mi-app-node
- PM2 ofrece varios comandos útiles para gestionar la aplicación:
- Ver el estado de la aplicación:
bash
Copiar código
pm2 status
bash
Copiar código
pm2 restart mi-app-node
-
- Detener la aplicación:
bash
Copiar código
pm2 stop mi-app-node
- Configura PM2 para que inicie la aplicación automáticamente cuando el servidor se reinicie:
bash
Copiar código
pm2 startup
pm2 save
Ahora, tu aplicación está gestionada por PM2, lo cual garantiza que se reiniciará automáticamente si falla.
Paso 5: Configurar Nginx como un Proxy Inverso
Nginx es un servidor web ligero y eficiente que también funciona muy bien como un proxy inverso. Configurar Nginx como proxy inverso frente a la aplicación Node.js ofrece varios beneficios, como el balanceo de carga y una capa de seguridad adicional.
- Instala Nginx:
bash
Copiar código
sudo apt install nginx -y
- Configura Nginx para que redirija el tráfico hacia tu aplicación Node.js. Crea un nuevo archivo de configuración para tu sitio en /etc/nginx/sites-available/mi-app-node:
bash
Copiar código
sudo nano /etc/nginx/sites-available/mi-app-node
- Agrega la siguiente configuración al archivo:
nginx
Copiar código
server {
listen 80;
server_name direccion-ip-del-servidor;
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;
}
}
-
- Reemplaza direccion-ip-del-servidor por la dirección IP de tu servidor o el nombre de dominio, si tienes uno configurado.
- Habilita el nuevo sitio en Nginx:
bash
Copiar código
sudo ln -s /etc/nginx/sites-available/mi-app-node /etc/nginx/sites-enabled/
- Prueba la configuración de Nginx para asegurarte de que no hay errores de sintaxis:
bash
Copiar código
sudo nginx -t
- Reinicia Nginx para que los cambios surtan efecto:
bash
Copiar código
sudo systemctl restart nginx
Ahora, al visitar la dirección IP del servidor o el dominio configurado, deberías ver la respuesta de la aplicación Node.js que creaste.
Paso 6: Implementar HTTPS con Certbot y Let’s Encrypt
Para asegurar el tráfico entre el cliente y el servidor, es recomendable habilitar HTTPS utilizando Certbot y Let’s Encrypt.
- Instala Certbot:
bash
Copiar código
sudo apt install certbot python3-certbot-nginx -y
- Obtén y configura el certificado SSL:
bash
Copiar código
sudo certbot –nginx -d tu-dominio
- Sigue las instrucciones en pantalla para completar la configuración del certificado.
Certbot renovará automáticamente el certificado cuando esté a punto de expirar.
Paso 7: Optimización y Configuraciones Adicionales
Configuración de Firewalls
Asegúrate de permitir el tráfico solo a los puertos necesarios. Por ejemplo, en una configuración básica se deben permitir los puertos 22 (SSH), 80 (HTTP) y 443 (HTTPS).
bash
Copiar código
sudo ufw allow OpenSSH
sudo ufw allow ‘Nginx Full’
sudo ufw enable
Habilitar Compresión Gzip en Nginx
Para mejorar el rendimiento, activa la compresión Gzip en el archivo /etc/nginx/nginx.conf:
nginx
Copiar código
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
Reinicia Nginx tras realizar los cambios.
Configurar un servidor Node.js en la nube utilizando Nginx y PM2 es una excelente forma de crear un entorno de producción seguro y de alto rendimiento. Nginx se encarga del proxy inverso y facilita la configuración de HTTPS, mientras que PM2 administra y monitorea el proceso de Node.js, asegurando que esté siempre en funcionamiento.
Con esta configuración, puedes enfocarte en desarrollar y escalar tu aplicación sabiendo que la infraestructura es robusta y confiable.
Buenas Prácticas para Optimizar y Monitorear un Servidor Node.js en Producción
Una vez configurado el servidor Node.js con Nginx y PM2, es importante implementar prácticas adicionales para optimizar el rendimiento y mejorar la seguridad. Aquí te presento algunas recomendaciones que ayudarán a fortalecer la confiabilidad de tu aplicación en el entorno de producción.
1. Configuración de Logs en Nginx y PM2
Registrar los eventos del servidor es crucial para monitorear el rendimiento y solucionar problemas cuando se presentan. Tanto Nginx como PM2 ofrecen herramientas de registro de logs que puedes configurar para almacenar información relevante.
- Nginx genera dos tipos de logs: el log de acceso y el log de errores. Para personalizar la configuración, edita el archivo de configuración en /etc/nginx/nginx.conf o en el archivo específico del sitio dentro de /etc/nginx/sites-available/mi-app-node.
nginx
Copiar código
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
- PM2 también registra logs que puedes consultar para evaluar el estado de tu aplicación:
bash
Copiar código
pm2 logs mi-app-node
Es buena práctica configurar el almacenamiento de estos logs para evitar que se saturen con datos antiguos. PM2 ofrece un comando para limitar el tamaño de los logs, limpiándolos cuando alcanzan un umbral especificado:
bash
Copiar código
pm2 install pm2-logrotate
Con esta configuración, PM2 gestionará automáticamente los archivos de log para evitar problemas de almacenamiento en el servidor.
2. Seguridad en la Configuración del Servidor
Asegurar la infraestructura de un servidor es vital para proteger los datos y la estabilidad de la aplicación. Aquí tienes algunas medidas adicionales de seguridad:
- Desactivar el acceso al puerto HTTP (80): Después de configurar HTTPS, desactiva el acceso a HTTP para que todo el tráfico esté encriptado. Para ello, puedes añadir una redirección en el archivo de configuración de Nginx:
nginx
Copiar código
server {
listen 80;
server_name tu-dominio;
return 301 https://$host$request_uri;
}
- Mantener los paquetes actualizados: Ejecuta actualizaciones de seguridad de tu sistema operativo con regularidad. En servidores basados en Debian o Ubuntu, puedes realizar esto con:
bash
Copiar código
sudo apt update && sudo apt upgrade -y
- Configurar SSH con autenticación de claves: Para proteger el acceso SSH, considera usar autenticación basada en claves en lugar de contraseñas y cambiar el puerto de SSH para evitar ataques de fuerza bruta.
- Genera una clave SSH en tu máquina local:
bash
Copiar código
ssh-keygen -t rsa -b 4096
-
- Agrega la clave pública al archivo ~/.ssh/authorized_keys en el servidor remoto.
- Habilitar un firewall: Si aún no lo has hecho, activar y configurar un firewall es una medida sencilla pero efectiva para proteger tu servidor.
bash
Copiar código
sudo ufw enable
3. Monitoreo de la Aplicación con PM2 y Servicios Externos
PM2 ofrece opciones avanzadas de monitoreo que te permiten visualizar el uso de recursos de tu aplicación en tiempo real. Además, puedes integrar tu servidor con servicios externos para obtener métricas detalladas.
- PM2 monitoreo básico: El comando pm2 monit muestra el uso de la CPU y memoria, ayudándote a identificar cuellos de botella en la aplicación.
bash
Copiar código
pm2 monit
- Integración con servicios de monitoreo: Hay diversas herramientas de monitoreo que puedes integrar con Node.js, como New Relic, Datadog o Grafana. Estas plataformas proporcionan información detallada sobre el uso de la CPU, latencia de respuesta, solicitudes por segundo, y mucho más.
Para empezar con New Relic, por ejemplo, instala su agente para Node.js:
bash
Copiar código
npm install newrelic –save
Luego, configura el agente con tu clave de licencia y comienza a recibir métricas detalladas en el panel de New Relic.
4. Gestión de Variables de Entorno
Es importante mantener la configuración de tu aplicación separada del código fuente para simplificar el mantenimiento y la seguridad. Esto se logra mediante el uso de variables de entorno, almacenadas en un archivo .env o configuradas directamente en PM2.
- Crea un archivo .env en la raíz de tu proyecto:
plaintext
Copiar código
PORT=3000
NODE_ENV=production
DB_URL=mongodb://usuario:contraseña@host:puerto/baseDeDatos
- Usa el paquete dotenv para cargar las variables de entorno en tu aplicación:
bash
Copiar código
npm install dotenv
Y agrégalo en tu app.js:
javascript
Copiar código
require(‘dotenv’).config();
const PORT = process.env.PORT || 3000;
- Configura PM2 para cargar las variables del archivo .env:
bash
Copiar código
pm2 start app.js –env production
Usar variables de entorno permite una mayor flexibilidad al hacer despliegues en diferentes entornos, como desarrollo, prueba y producción.
5. Escalabilidad y Balanceo de Carga con Nginx y PM2
Para aplicaciones de alto tráfico, la escalabilidad es un factor clave. Nginx y PM2 permiten configurar múltiples instancias de la aplicación para distribuir la carga de trabajo entre los núcleos de la CPU disponibles.
- Clustering con PM2: PM2 tiene una funcionalidad de clustering que permite ejecutar múltiples instancias de tu aplicación en paralelo.
bash
Copiar código
pm2 start app.js -i max
El parámetro -i max ejecutará una instancia por núcleo disponible de la CPU, maximizando el uso de recursos.
- Configuración de balanceo de carga con Nginx: En lugar de un solo servidor, Nginx puede distribuir las solicitudes entre varios servidores o instancias de la aplicación. Esta configuración se logra modificando el archivo de configuración de Nginx.
nginx
Copiar código
upstream mi-app {
server localhost:3000;
server localhost:3001;
}
server {
listen 80;
server_name tu-dominio;
location / {
proxy_pass http://mi-app;
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;
}
}
Con esta configuración, Nginx distribuirá las solicitudes entrantes entre las diferentes instancias configuradas en el bloque upstream.
6. Configuración de Backups y Plan de Recuperación
Los fallos de hardware o software pueden suceder, por lo que es crucial contar con una estrategia de backups. Asegúrate de implementar respaldos regulares de la base de datos y archivos críticos.
- Backups de la Base de Datos: Si usas una base de datos como MongoDB o MySQL, crea una tarea cron para realizar backups periódicos.
bash
Copiar código
# Ejemplo de backup diario para MySQL
0 2 * * * mysqldump -u usuario -p’contraseña’ nombre_base_de_datos > /ruta/del/backup.sql
- Backups de Archivos: Puedes crear un script que comprima y respalde archivos importantes en un servicio de almacenamiento en la nube o en otro servidor.
- Plan de Recuperación: Además de los respaldos, documenta un plan de recuperación detallado para que, en caso de un fallo, puedas restaurar rápidamente el servidor y minimizar el tiempo de inactividad.
Configurar un servidor Node.js en producción no se limita solo a instalar y ejecutar la aplicación; requiere establecer prácticas de optimización, monitoreo y seguridad. Al seguir estas recomendaciones, se garantiza una aplicación sólida y preparada para soportar el tráfico y los desafíos de un entorno de producción en la nube.