Objetivos de aprendizaje
Después de leer este artículo podrás:
- Iniciar una app con PM2 y configurar el reinicio automático
- Limitar la memoria y los bucles de fallos con max_memory_restart y max_restarts
- Saber cuándo usar pm2-runtime en un contenedor o prescindir de PM2
Un proceso Node.js que lanza una excepción sin manejar simplemente muere. Si nadie lo vuelve a levantar, tu bot, API o sitio web se queda caído hasta que te das cuenta. Un supervisor de procesos resuelve eso: vigila tu app y la reinicia cuando se cae. En el ecosistema Node.js, el más usado es PM2.
¿Cómo instalas PM2 e inicias una app?#
Con Node.js instalado (consulta cómo hospedar una app Node.js), instálalo de forma global e inicia tu archivo principal:
npm install pm2 -g
pm2 start app.js --name mi-app
pm2 list
pm2 logs mi-apppm2 list muestra el estado de cada proceso, pm2 logs sigue la salida en tiempo real y pm2 restart mi-app reinicia a mano. Para detener y quitar de la lista, usa pm2 stop mi-app y pm2 delete mi-app.
Por defecto, autorestart es true: si la app falla o termina, PM2 la vuelve a levantar. Para un script de una sola ejecución (una migración, por ejemplo), desactívalo con --no-autorestart.
¿Cómo usas un ecosystem file?#
Pasar flags por la línea de comandos no escala. El ecosystem file reúne toda la configuración en un archivo versionado:
// ecosystem.config.js
module.exports = {
apps: [
{
name: "mi-app",
script: "./app.js",
max_memory_restart: "300M",
max_restarts: 10,
restart_delay: 3000,
kill_timeout: 5000,
env: { NODE_ENV: "development" },
env_production: { NODE_ENV: "production" },
},
],
};Inícialo con pm2 start ecosystem.config.js --env production. El bloque env_production solo se aplica cuando pasas --env production. Nunca guardes secretos (tokens, contraseñas) en ese archivo: léelos de variables de entorno. El archivo usa CommonJS (module.exports); si tu package.json tiene "type": "module", llámalo ecosystem.config.cjs.
¿Qué opciones de reinicio merecen la pena?#
| Opción | Qué hace |
|---|---|
autorestart |
Reinicia cuando el proceso se cae. Por defecto: true. |
max_memory_restart |
Reinicia cuando la memoria supera el límite ("300M", "1G"). PM2 lo comprueba cada 30 segundos. |
restart_delay |
Espera en milisegundos antes de reiniciar una app que se cayó. Por defecto: 0. |
exp_backoff_restart_delay |
Aumenta el intervalo con cada fallo, hasta 15 segundos. Vuelve a 0 tras 30 segundos estable. |
max_restarts |
Reinicios inestables seguidos antes de rendirse. Por defecto: 16. |
min_uptime |
Tiempo mínimo de vida para que la app cuente como iniciada. |
cron_restart |
Reinicio programado, por ejemplo "0 4 * * *" para las 4:00 todos los días. |
stop_exit_codes |
Códigos de salida que no disparan un reinicio ([0]). |
Dos de estas opciones piden cuidado.
max_memory_restart esconde una fuga de memoria, no la arregla. Es un parche útil mientras investigas. Si la app se reinicia cada hora por memoria, el defecto sigue en el código.
Sin restart_delay, un error al arrancar se convierte en un bucle cerrado. La app se cae en milisegundos, PM2 la levanta y se vuelve a caer. Tras max_restarts fallos inestables seguidos, PM2 marca la app como errored y deja de intentarlo. Usa restart_delay o exp_backoff_restart_delay para dar margen a dependencias externas, como una base de datos que todavía está arrancando.
¿PM2 arranca solo cuando el servidor se reinicia?#
No, a menos que se lo pidas. Son dos comandos:
pm2 startup
pm2 savepm2 startup detecta el sistema de init (systemd, por ejemplo) e imprime el comando que registra PM2 en el arranque: cópialo y ejecútalo (con sudo) antes de pm2 save. pm2 save guarda la lista actual de apps, y PM2 la restaura cuando el servidor arranca. Para restaurarla a mano, usa pm2 resurrect. Después de actualizar Node.js, ejecuta pm2 unstartup y otra vez pm2 startup, para que el servicio apunte al binario nuevo.
¿Cómo usas PM2 dentro de Docker?#
En un contenedor (consulta qué es Docker), usa pm2-runtime, un sustituto del binario node que se ejecuta en primer plano, como espera un contenedor:
FROM node:lts
WORKDIR /app
COPY . .
RUN npm install
RUN npm install pm2 -g
CMD ["pm2-runtime", "ecosystem.config.js"]PM2 reenvía las señales de cierre a la app. Escucha SIGINT para cerrar conexiones antes de salir: PM2 espera 1600 ms por defecto antes del SIGKILL, algo que se ajusta con kill_timeout. Para un proceso por contenedor, añade --only nombre-de-la-app.
En la mayoría de los casos, sin embargo, PM2 dentro de Docker es redundante: la política de reinicio del propio contenedor ya recrea el proceso que murió.
¿Cuándo prescindir de PM2?#
PM2 solo tiene sentido cuando administras la máquina tú mismo, como en un VPS. Si la plataforma ya reinicia el proceso que se detuvo, se convierte en una capa más que mantener. Un contenedor bajo un orquestador, un servicio de systemd con Restart=always o un hosting con reinicio automático cumplen el mismo papel.
Ten en cuenta que PM2 solo recrea el proceso: no corrige el bug que tumbó la app. Registra los errores y lee los logs (consulta cómo leer los logs de una app) para encontrar la causa.
Cómo hacerlo en Square Cloud#
En Square Cloud, PM2 no es necesario ni recomendable. Los contenedores están siempre encendidos, sin modo de suspensión. El reinicio automático existe en todos los planes y viene activado cuando despliegas desde el panel (en un squarecloud.app escrito a mano, usa AUTORESTART=true): vuelve a levantar el proceso que termina con error.
Despliegas subiendo un ZIP, con la CLI, desde GitHub o con la extensión de VS Code. Si la app necesita configuración, define las variables de entorno en el panel: el cambio se aplica en el siguiente reinicio, sin rebuild. Los logs aparecen en tiempo real en el panel y en la CLI, lo que ayuda a encontrar el motivo de una caída.
Una salvedad: el reinicio automático recrea el proceso, pero no corrige un error de código ni una fuga de memoria. Si la app supera la RAM asignada, se detiene y no vuelve sola: aumenta la memoria en los ajustes, iníciala de nuevo e investiga la causa. Para ver cómo encaja esto en un bot, lee cómo mantener un bot de Discord 24/7.
Mira lo que incluye el hosting en Funcionalidades.
Deploy
Sube desde GitHub, la CLI o un ZIP y publica en segundos
Preguntas frecuentes
¿PM2 reinicia la app solo si se cae?
Sí. autorestart viene activado por defecto: si el proceso falla o termina, PM2 lo vuelve a levantar. Para scripts de una sola ejecución, usa --no-autorestart.
¿Cómo hago que PM2 arranque junto con el servidor?
Ejecuta pm2 startup y lanza con sudo el comando que imprime. Después, con las apps en marcha, usa pm2 save para guardar la lista que se restaurará en el arranque.
¿Necesito PM2 dentro de un contenedor Docker?
Normalmente no. El orquestador o la política de reinicio del contenedor ya recrea el proceso. Si quieres PM2 ahí, usa pm2-runtime, pensado para ejecutarse en primer plano.
¿Por qué mi app queda en estado errored en PM2?
PM2 se rinde después de 16 reinicios inestables seguidos (max_restarts). Lee los logs con pm2 logs, corrige la causa y vuelve a levantarla con pm2 restart.
Más en Deploy
Ver los 33 artículos- Qué son las variables de entornoLas variables de entorno son pares clave-valor que el sistema operativo entrega a un proceso al iniciar. Aprende a leerlas en Node.js y Python sin exponer tokens.
- Qué es un deploy o despliegueUn deploy o despliegue lleva una versión de tu código a un servidor, la prepara y la pone en marcha. Conoce las etapas, los métodos y cómo hacer rollback.
- ¿Cuánta RAM y CPU necesita mi aplicación?Dimensiona RAM y CPU midiendo el pico real de la aplicación y sumando un margen del 30%. Mira cómo medir en Node.js, Python y Java y qué hacer cuando falte.
- Deploy automático con GitHub ActionsEl deploy automático con GitHub Actions envía tu código al servidor en cada push. Mira el workflow paso a paso, los secrets, las pruebas y los errores comunes.