Gestión de procesos persistentes con PM2 para aplicaciones modernas

PM2 es la herramienta de facto para ejecutar y mantener procesos Node.js en producción. Esta guía práctica explica cómo instalar, configurar y operar procesos persistentes con PM2, aprovechar clustering, reinicios sin downtime, integración con systemd y buenas prácticas para despliegues confiables en servidores Linux.

Por qué usar PM2 en producción

PM2 (Process Manager 2) ofrece un conjunto de funcionalidades orientadas a mantener aplicaciones en ejecución de manera confiable y observable. Está diseñado para entornos de microservicios, APIs y aplicaciones en tiempo real que requieren alta disponibilidad. Entre sus beneficios destacan:

  • Reinicio automático tras fallos o límites de memoria.
  • Modo cluster para aprovechar múltiples núcleos CPU.
  • Reloads sin downtime (graceful reload) y zero-downtime restarts.
  • Logs centralizados y compatibilidad con rotación externa.
  • Integración con herramientas de monitoreo y paneles.

PM2 acelera la estabilidad operativa y reduce el trabajo manual sobre procesos persistentes en servidores.

Instalación y primer arranque

Instalar PM2 es sencillo con npm. En un servidor con Node.js instalado:

sudo npm install -g pm2
pm2 --version

Para arrancar una aplicación:

pm2 start app.js --name api-backend

Comandos esenciales:

  • pm2 list — ver procesos gestionados.
  • pm2 logs api-backend — seguir logs en tiempo real.
  • pm2 stop/restart/delete <name|id> — controlar procesos.

Configuración avanzada: ecosystem file

Para entornos reproducibles y CI/CD es recomendable usar un archivo ecosystem.config.js. Ejemplo:

module.exports = {
  apps: [{
    name: 'api-backend',
    script: './dist/server.js',
    instances: 'max',
    exec_mode: 'cluster',
    env: { NODE_ENV: 'production' },
    max_memory_restart: '300M',
    watch: false
  }]
};

Este archivo permite definir instancias, modo de ejecución, variables de entorno y políticas de reinicio. Arrancar con pm2 start ecosystem.config.js facilita despliegues consistentes.

Clustering y escalado en el mismo host

PM2 implementa clustering nativo para Node.js. En el modo cluster PM2 crea múltiples procesos worker que comparten el mismo puerto, permitiendo utilizar todos los núcleos CPU disponibles:

  • instances: 'max' crea tantos workers como núcleos.
  • Balance de carga interno basado en round-robin (desde Node 16+ o según configuración).

Clustering es ideal cuando la aplicación es CPU-bound o necesita manejar muchas conexiones concurrentes. Para balanceo entre hosts usa un proxy inverso como NGINX o una solución de orquestación (Kubernetes, Docker Swarm).

Reloads sin downtime y estrategias de actualización

PM2 soporta reloads sin interrumpir conexiones activas mediante:

  • pm2 reload <name> — reinicia workers uno por uno evitando caídas.
  • pm2 gracefulReload <name> — para scripts que implementen hooks de cierre suave.

Práctica recomendada para despliegues:

  • Uso de pm2 reload tras actualizar artefactos para minimizar impacto.
  • Pruebas de smoke en un worker antes de reload completo.
  • Scripts de health check y readiness para orquestadores externos.

Logs, rotación y observabilidad

PM2 centraliza stdout y stderr en archivos por proceso. Para producción es imprescindible gestionar rotación y retención:

  • pm2 install pm2-logrotate — plugin oficial para rotación por tamaño y fecha.
  • Integración con soluciones externas como ELK/EFK, Datadog o Grafana a través de agentes.

Para diagnósticos, PM2 ofrece pm2 monit y exportes de métricas. Complementa con trazas distribuidas y métricas de aplicación para detectar memory leaks o picos de latency. En la arquitectura, recuerda que el event loop y callbacks afectan el rendimiento; una lectura sobre el event loop ayuda a interpretar métricas de latencia.

Persistencia entre reinicios del sistema

Para garantizar procesos persistentes tras un reboot del servidor, genera un script de inicio con:

pm2 startup systemd
pm2 save

El primer comando imprime un comando adicional que hay que ejecutar con privilegios para registrar el servicio systemd. Después, pm2 save guarda el estado actual para restauración automática.

Integración con reverse proxy y HTTPS

En producción conviene situar PM2 detrás de un proxy inverso como NGINX o un balanceador. Esto habilita:

  • Manejo centralizado de certificados TLS (por ejemplo con Let\’s Encrypt).
  • Rate limiting, compresión y caching a nivel HTTP.
  • Health checks y reintentos desde el proxy.

Ejemplo básico de configuración NGINX para proxy a una app en 3000:

server {
  listen 80;
  server_name api.example.com;

  location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_set_header Host $host;
  }
}

Buenas prácticas operativas

  • Definir límites de memoria (max_memory_restart) para reinicios automáticos por fugas.
  • Evitar watch en producción: en su lugar, desplegar artefactos y reiniciar con PM2.
  • Separar logs de la aplicación y del sistema; usar rotación y centralización.
  • Estandarizar ecosystem.config.js en repositorio para reproducibilidad.
  • Implementar health checks y metrics endpoints para integración con alerting.

Solución de problemas comunes

Proceso que se cae continuamente

  • Revisar logs con pm2 logs y stderr. Identificar excepciones no capturadas.
  • Configurar --max-memory-restart para detectar leaks y reiniciar antes de colapsar.

Memoria creciente sin explicación

  • Hacer heap snapshots y revisar dependencias nativas o caches en memoria.
  • Considerar reinicios programados fuera de horario crítico si no se puede corregir inmediatamente.

Seguridad y mantenimiento

Mantén PM2 y Node actualizados, limita accesos SSH y usa cuentas de servicio sin privilegios. Evita exponer paneles de administración o puertos internos. Para certificados TLS automatizados, integra Let\’s Encrypt con renovaciones automáticas gestionadas en el proxy.

Casos reales y recomendaciones finales

En aplicaciones que requieren alta disponibilidad (APIs públicas, webs con tráfico variable), PM2 reduce el downtime y facilita el escalado vertical (multiples workers en un host). Para escalado horizontal combina PM2 con balanceadores y/o contenedores orquestados. Si gestionas múltiples microservicios, automatiza el despliegue de ecosystem.config.js y centraliza logs/metrics.

Conclusión

PM2 es una solución madura para gestionar procesos persistentes en entornos Node.js y microservicios. Proporciona clustering, reinicio automático, reloads sin downtime y herramientas de observabilidad que aceleran la estabilidad operativa. Implementa un ecosystem.config.js reproducible, activa rotación de logs, configura arranque con systemd y coloca un proxy inverso como NGINX delante de la aplicación. Con estas prácticas obtendrás despliegues más seguros, observables y resilientes.

Para profundizar en conceptos técnicos sobre el event loop consulta la documentación de MDN Web Docs y revisa la documentación oficial de PM2 para opciones avanzadas y plugins.