---
title: "Gestor de procesos PM2: guía completa para gestionar apps"
description: "Aprende a usar el gestor de procesos PM2 para ejecutar apps Node.js, Python y Bun en producción. Cubre instalación, clustering, gestión de logs, reinicios automáticos y más."
date: 2024-01-19
categories: ["tools"]
tags: ["pm2","node","process-manager"]
---

import { Picture } from "astro:assets";
import imag1 from "@assets/images/24/01/pm2-monit.png";
import Notice from "@components/widgets/Notice.astro";
import ListCheck from "@components/widgets/ListCheck.astro";
import Accordion from "@components/widgets/Accordion.astro";
import Tabs from "@components/widgets/Tabs.astro";
import Tab from "@components/widgets/Tab.astro";

PM2 es un gestor de procesos de producción para aplicaciones Node.js, Python y Bun. Ejecuta tus apps como daemons en segundo plano, gestiona reinicios automáticos tras fallos, ofrece clustering con balanceo de carga y te da un panel en el terminal para monitorizarlo todo. Si despliegas apps en un VPS, ya sea una máquina de [Hetzner Cloud](https://go.bitdoze.com/hetzner) o un [VPS de Hostinger](https://go.bitdoze.com/hostinger-vps), PM2 es una de las formas más rápidas de conseguir una gestión de procesos de nivel producción sin la sobrecarga de contenedores ni orquestación.

_Los precios de los VPS subieron en 2026 — si estás reconsiderando una máquina alquilada, mira [qué cambió y cuándo gana un mini PC](/es/subidas-precios-vps/)._

Uso PM2 en instancias VPS donde ejecuto varias apps Node.js o Python y necesito que sobrevivan a fallos y reinicios. No sustituye a Docker ni a Kubernetes, pero para una configuración de un solo servidor cubre bien lo básico: supervisión de procesos, clustering, gestión de logs y persistencia tras el arranque. La versión 7.x añadió soporte para Bun, trazado con OpenTelemetry y mejoró el diseño de la CLI. Todo ello merece la pena si llevas tiempo sin actualizar.

<Notice type="info" title="Actualizado para PM2 7.x">
Esta guía se publicó originalmente en enero de 2024 y se ha actualizado para PM2 7.x (última versión: 7.0.3). Los cambios clave incluyen soporte para el runtime Bun, requisito de Node.js 18+, trazado con OpenTelemetry y una CLI mejorada con diseño adaptativo.
</Notice>

## ¿Qué es el gestor de procesos PM2?

[PM2](https://pm2.keymetrics.io/) es un gestor de procesos de código abierto para aplicaciones Node.js/Bun que también gestiona runtimes de Python, Ruby, PHP y otros. Tiene más de 600 millones de descargas en npm y más de 43 000 estrellas en GitHub. Empresas como Microsoft, Netflix, NASA e IBM lo usan en producción.

PM2 ejecuta tus aplicaciones como procesos daemon, de modo que no bloquean tu terminal. Soporta el modo cluster para balancear la carga entre los núcleos de CPU, reinicios automáticos cuando los procesos fallan o superan los límites de memoria, gestión centralizada de logs y un panel de monitorización. Está licenciado bajo AGPL 3.0.

Lo clave que resuelve PM2 es la supervisión de procesos. Sin un gestor de procesos, si tu app Node.js falla a las 3 de la madrugada, seguirá caída hasta que la reinicies manualmente. PM2 vigila los fallos y levanta el proceso automáticamente. También se encarga de la fontanería de ejecutar múltiples instancias repartidas entre los núcleos de CPU. Sin PM2, tendrías que escribir el código de cluster tú mismo o configurar systemd con varias unidades de servicio.

<ListCheck>
<ul>
<li>Ejecuta apps como daemons en segundo plano (sin necesidad de terminal)</li>
<li>Modo cluster con balanceo de carga entre núcleos de CPU</li>
<li>Reinicios automáticos por fallo, límite de memoria o programación cron</li>
<li>Visualización y rotación centralizada de logs</li>
<li>Panel de monitorización en el terminal (CPU, memoria, event loop)</li>
<li>Multi-runtime: Node.js, Python, Bun, Deno, Ruby, PHP</li>
</ul>
</ListCheck>

## Cómo instalar PM2

PM2 es un módulo de Node.js, así que primero necesitas Node.js y npm en tu sistema. PM2 v7.x requiere **Node.js >= 18.0.0** (dejó de soportar Node 16). Si aún no tienes Node.js, puedes [instalar Node.js usando NVM](/es/instalar-nodejs-nvm-macos-ubuntu/). NVM es la forma recomendada de instalar Node.js en un servidor porque te permite cambiar de versión sin afectar al sistema.

Instala PM2 globalmente:

```sh
npm install -g pm2
```

Verifica la instalación:

```sh
pm2 --version
```

Salida esperada:

```
[PM2] PM2 Successfully daemonized
7.0.3
```

<Notice type="warning" title="¿command not found?">
Si obtienes `command not found`, el directorio bin global de npm no está en tu `$PATH`. Ejecuta `npm config get prefix` y añade el directorio `/bin` a tu PATH.
</Notice>

<Notice type="info" title="Actualizar desde una versión anterior">
Si ya tienes PM2 instalado, usa `pm2 update` en lugar de reinstalarlo. Guarda la lista de procesos, mata el daemon antiguo y restaura todo con la nueva versión sin perder procesos.
</Notice>

## Gestión de aplicaciones con PM2

Esta sección cubre cómo ejecutar apps desde la línea de comandos y con archivos de configuración, con buenas prácticas para cada runtime.

### Inicio rápido: ejecutar apps desde la línea de comandos

La forma más rápida de arrancar una app con PM2:

```sh
# Node.js
pm2 start app.js --name my-node-app

# Python
pm2 start app.py --name my-python-app --interpreter python3

# Streamlit
pm2 start 'streamlit run app.py' --name my-streamlit-app
```

Salida en el terminal:

```
[PM2] Starting /usr/bin/bash in fork_mode (1 instance)
[PM2] Done.
┌────┬─────────────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name                │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
├────┼─────────────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0  │ my-streamlit-app    │ default     │ N/A     │ fork    │ 9484     │ 0s     │ 0    │ online    │ 0%       │ 10.3mb   │ root     │ disabled │
└────┴─────────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
```

Para más información sobre cómo desplegar apps Streamlit de esta forma, consulta [desplegar Streamlit en un VPS con PM2](/es/desplegar-streamlit-vps-cloudflare/).

### Buenas prácticas para apps Node.js

Node.js es el runtime nativo de PM2. Esto es lo que debes tener en cuenta:

- **El modo cluster es opcional, no el predeterminado.** PM2 se ejecuta en modo `fork` por defecto (un proceso). Para usar el [modo cluster](/es/pm2-fork-cluster/), tienes que indicar explícitamente `exec_mode: "cluster"` e `instances: "max"` en tu configuración o usar `-i max` en la línea de comandos. Es una fuente habitual de confusión: `pm2 start app.js` te da un solo proceso, no un cluster.
- **Usa `--watch` durante el desarrollo** para recargar automáticamente al cambiar el código. No lo uses en producción. Añade sobrecarga al sistema de archivos y puede provocar reinicios inesperados si se escriben archivos temporales o logs dentro del directorio vigilado.
- **Usa `ecosystem.config.js`** para producción (ver la siguiente sección). Es el formato de configuración recomendado y soporta cambio de entorno (`env`, `env_production`).
- **Configura `max_memory_restart`** para detectar fugas de memoria. Para una app típica de Express/Fastify, `"300M"` a `"512M"` es un punto de partida razonable. La app se reiniciará limpiamente al alcanzar el umbral.
- **Para servidores HTTP en modo cluster**, usa `pm2 reload` en lugar de `pm2 restart`. Reload hace un reinicio gradual de los workers, así que no hay tiempo de inactividad para las peticiones en curso.

### Buenas prácticas para apps Python

PM2 puede ejecutar cualquier app Python: Flask, FastAPI, Streamlit, scripts y más:

- **Especifica el intérprete**: usa `--interpreter python3` (o la ruta completa si tienes varias versiones de Python). Si no lo especificas, PM2 puede elegir el equivocado.
- **Usa el modo fork**: el GIL de Python hace que el modo cluster no tenga sentido. Varios procesos Python en modo cluster no comparten memoria ni balancean carga como lo hacen los workers de Node.js. Quédate con el modo `fork` y usa un número fijo de instancias si necesitas varios workers.
- **Desactiva el reinicio automático para scripts de un solo uso**: usa `--no-autorestart` para evitar bucles de reinicio infinitos en scripts que terminan normalmente con código de salida 0. Sin este flag, PM2 reiniciará cualquier script que termine, lo que normalmente no es lo que quieres para trabajos por lotes o scripts de procesamiento de datos.
- **Configura `max_memory_restart`** para apps web Python de larga duración. Las apps Flask y FastAPI pueden acumular memoria con el tiempo, sobre todo con dataframes grandes o caché. Un valor como `"500M"` es un punto de partida razonable.

### Soporte de Bun y Deno en PM2

PM2 v7.x tiene soporte nativo para Bun. Los archivos TypeScript (`.ts`, `.tsx`) detectan Bun automáticamente cuando está instalado:

```sh
# Los archivos TypeScript detectan Bun automáticamente
pm2 start app.ts

# Intérprete Bun explícito
pm2 start index.js --interpreter bun

# Modo cluster de Bun (requiere Bun >= 1.1.25)
bunx --bun pm2 start app.ts -i max

# Deno
pm2 start main.ts --interpreter deno --interpreter-args "run --allow-net"
```

El soporte de Bun es todavía relativamente nuevo. El modo cluster funciona con Bun >= 1.1.25, y el prefijo `bunx --bun` garantiza que el propio PM2 se ejecuta bajo Bun en lugar de Node.js. El soporte de Deno funciona mediante el flag `--interpreter` con argumentos pasados vía `--interpreter-args`.

<Notice type="warning" title="Runtime fijado">
El daemon de PM2 conserva el runtime con el que se inició por primera vez. Si cambias entre Node.js y Bun, ejecuta `pm2 kill` primero para reiniciar el daemon con el nuevo runtime.
</Notice>

Si estás explorando Bun como runtime, consulta el [gestor de paquetes Bun](/es/gestor-paquetes-bun/) para una comparación completa con npm, yarn y pnpm.

## Archivos de configuración ecosystem de PM2

Para cualquier cosa más allá de pruebas rápidas, usa un archivo de configuración ecosystem. Es la forma recomendada de declarar tus apps. El archivo ecosystem es un módulo JavaScript que exporta la configuración de tus aplicaciones. Soporta múltiples apps, variables específicas por entorno y es más fácil de mantener que comandos CLI ad hoc.

### Uso de `pm2 init simple` para generar una configuración

Ejecuta esto en el directorio de tu proyecto:

```sh
pm2 init simple
```

Genera un `ecosystem.config.js` inicial:

```js
module.exports = {
  apps: [{
    name: "my-app",
    script: "./app.js",
    instances: "max",
    exec_mode: "cluster",
    env: {
      NODE_ENV: "development"
    },
    env_production: {
      NODE_ENV: "production"
    }
  }]
}
```

Arranca con un entorno específico:

```sh
pm2 start ecosystem.config.js --env production
```

### Archivos ecosystem en JSON vs JavaScript

PM2 soporta ambos formatos. Así se ve cada uno en una configuración multi-app:

<Tabs>
<Tab name="ecosystem.config.js (recomendado)">
```js
module.exports = {
  apps: [
    {
      name: "api-server",
      script: "./server.js",
      instances: "max",
      exec_mode: "cluster",
      env: {
        NODE_ENV: "development"
      },
      env_production: {
        NODE_ENV: "production"
      }
    },
    {
      name: "streamlit-app",
      script: "streamlit",
      args: "run app.py",
      cwd: "/path/to/streamlit/app",
      interpreter: "python3",
      instances: 1,
      max_memory_restart: "1G",
      error_file: "/var/log/pm2/streamlit-error.log",
      out_file: "/var/log/pm2/streamlit-out.log",
      merge_logs: true
    }
  ]
}
```
</Tab>
<Tab name="Configuración JSON (sigue funcionando)">
```json
{
  "apps": [
    {
      "name": "api-server",
      "script": "./server.js",
      "instances": "max",
      "exec_mode": "cluster",
      "env": {
        "NODE_ENV": "development"
      }
    },
    {
      "name": "streamlit-app",
      "script": "streamlit",
      "args": ["run", "app.py"],
      "cwd": "/path/to/streamlit/app",
      "interpreter": "python3",
      "instances": 1,
      "max_memory_restart": "1G",
      "log_date_format": "YYYY-MM-DD HH:mm Z",
      "error_file": "/var/log/pm2/streamlit-error.log",
      "out_file": "/var/log/pm2/streamlit-out.log",
      "merge_logs": true
    }
  ]
}
```
</Tab>
</Tabs>

Campos clave de la configuración explicados:

- `name`: nombre del proceso que aparece en `pm2 list`. Elige algo descriptivo. Lo usarás en cada comando de PM2.
- `script`: archivo de entrada que ejecuta PM2.
- `interpreter`: runtime (`python3`, `bun`, `node`, etc.). PM2 lo detecta automáticamente para archivos `.js`, pero tienes que especificarlo para Python y otros runtimes.
- `instances`: número de instancias. Usa `"max"` para igualar los núcleos de CPU (solo útil con el modo cluster). Por defecto es `1`.
- `exec_mode`: `"fork"` (por defecto) o `"cluster"` (balanceo de carga, solo Node.js/Bun).
- `env` / `env_production`: [variables de entorno](/es/pm2-variables-entorno/) por entorno. Usa `--env production` para seleccionarlas. Es una de las principales ventajas de los archivos ecosystem frente a los comandos CLI.
- `max_memory_restart`: reinicia cuando la memoria supera este valor. Acepta cadenas legibles: `"300M"`, `"1G"`, `"512K"`. Un número sin unidad se interpreta como **bytes**, no megabytes. Por defecto: `0` (desactivado).
- `watch`: reinicia automáticamente al cambiar archivos. Útil en desarrollo, no en producción.

<Notice type="info" title="filter_env para seguridad">
PM2 soporta la opción `filter_env` para eliminar variables de entorno de los procesos hijo. Usa `filter_env: ["SECRET_"]` para filtrar por prefijo, o `filter_env: true` para eliminar todas las variables globales. Útil para endurecer despliegues en producción.
</Notice>

## Gestión de procesos desde la línea de comandos

La CLI de PM2 es la forma principal de interactuar con tus procesos. Los comandos son cortos y consistentes. Una vez aprendes el patrón, se vuelve memoria muscular.

### Iniciar, detener, reiniciar, recargar y eliminar

```sh
pm2 start <name|id>       # Inicia un proceso detenido
pm2 stop <name|id>        # Detiene de forma graceful
pm2 restart <name|id>     # Reinicio duro (corta las peticiones en curso)
pm2 reload <name|id>      # Recarga graceful: sin downtime en modo cluster
pm2 delete <name|id>      # Elimina el proceso de PM2 por completo
pm2 kill                  # Detiene el daemon y TODOS los procesos gestionados
```

La diferencia entre `restart` y `reload` importa en modo cluster: `reload` hace un reinicio gradual de los workers, así que no hay tiempo de inactividad. `restart` mata y recrea el proceso inmediatamente. Usa `reload` en producción. Usa `pm2 kill` al diagnosticar problemas o al cambiar de runtime. Es la opción nuclear que lo detiene todo.

### Comprobar el estado con `pm2 list` y `pm2 describe`

```sh
pm2 list                  # Todos los procesos (diseño adaptativo en v7.x)
pm2 describe <name|id>    # Info detallada: config, variables de entorno, reinicios, memoria
pm2 env <id>              # Variables de entorno de un proceso concreto
```

PM2 v7.x adapta la salida de `pm2 list` al ancho de tu terminal. Tabla completa en terminales anchos, condensada en los estrechos y un modo `mini` compacto en espacios muy reducidos. También muestra por defecto una línea de métricas del host (CPU, RAM, red). Actívala o desactívala con:

```sh
pm2 set pm2:sysmonit true    # Activa las métricas del sistema en pm2 ls
pm2 set pm2:sysmonit false   # Desactiva
```

`pm2 describe` es útil para depurar: muestra la configuración completa, las variables de entorno, el número de reinicios y las estadísticas de memoria/CPU de un proceso concreto. Usa `pm2 env <id>` cuando necesites comprobar con qué variables de entorno se está ejecutando realmente un proceso (útil cuando los archivos `.env` no se cargan correctamente).

## Gestión y rotación de logs en PM2

### Ver los logs

PM2 recoge stdout y stderr de todos los procesos gestionados en archivos de log (por defecto en `~/.pm2/logs/`). Puedes verlos con:

```sh
pm2 logs                      # Sigue todos los logs
pm2 logs <name|id>            # Sigue una app concreta
pm2 logs <name|id> --lines 100  # Últimas 100 líneas
pm2 logs <name|id> --err      # Solo stderr
pm2 logs <name|id> --out      # Solo stdout
pm2 flush                     # Vacía todos los archivos de log
```

`pm2 flush` vacía inmediatamente todos los archivos de log. Es útil cuando los logs han crecido demasiado y quieres empezar de cero después de configurar la rotación.

### Instalación y configuración de pm2-logrotate

<Notice type="warning" title="No es npm install">
`pm2 install pm2-logrotate` instala un **módulo** de PM2, no un paquete npm. NO uses `npm install pm2-logrotate`. Esta es la forma correcta de configurar la rotación de logs en PM2 — no existe un comando integrado `pm2 logrotate`.
</Notice>

```sh
# Instala el módulo
pm2 install pm2-logrotate

# Configuración
pm2 set pm2-logrotate:max_size 10M       # Rota cuando el archivo llega a 10 MB
pm2 set pm2-logrotate:retain 30          # Conserva 30 archivos rotados
pm2 set pm2-logrotate:compress true      # Comprime los archivos rotados
pm2 set pm2-logrotate:rotateInterval '0 0 * * *'  # Rota cada día a medianoche

# Ver la configuración actual
pm2 conf
```

Sin rotación de logs, los archivos de log de PM2 crecerán hasta llenar tu disco. Si eso ya te ha pasado, consulta [liberar espacio en disco](/es/limpiar-docker-completo/) para los pasos de recuperación.

## Monitorización del rendimiento con PM2

```sh
pm2 monit
```

Esto abre un panel en el terminal que muestra CPU, memoria, latencia del event loop y uso de red de todos los procesos gestionados. Puedes navegar entre procesos y ver sus logs en tiempo real. Es útil para depurar rápidamente: si un proceso se está comiendo toda la CPU, lo verás al instante.

<Picture formats={["webp"]} fallbackFormat="webp"
  src={imag1}
  alt="Panel de terminal del gestor de procesos PM2 mostrando CPU, memoria y métricas de procesos"
/>

Para una monitorización más amplia más allá de PM2 (CPU, memoria, disco y contenedores Docker a nivel de sistema), consulta [monitorizar recursos del servidor y Docker](/es/monitorizar-servidor/). La monitorización integrada de PM2 es solo a nivel de proceso: no te dirá nada sobre el espacio en disco, los contenedores Docker ni problemas a nivel de sistema.

## Despliegue en producción con PM2: reinicios automáticos y arranque

### Estrategias de reinicio

PM2 ofrece varias formas de mantener tus apps vivas. Entenderlas es importante para la fiabilidad en producción. Una estrategia de reinicio mal configurada puede dejar tu app caída o crear un bucle de reinicios que machaque tu base de datos.

**Campos básicos de reinicio** (en la configuración o en la CLI):

- `autorestart` — activa/desactiva los reinicios automáticos. Por defecto: `true`. Ponlo en `false` para scripts por lotes o tareas de un solo uso que deben ejecutarse una vez y terminar.
- `max_memory_restart` — reinicia cuando la memoria supera el umbral. Acepta cadenas legibles: `"300M"`, `"1G"`, `"512K"`. Un número sin unidad son **bytes**, no megabytes. Por defecto: `0` (desactivado). Es tu principal defensa contra las fugas de memoria.
- `min_uptime` — si la app termina antes de este tiempo (ms), se considera un fallo. Por defecto: `1000` (1 segundo). Auméntalo si tu app tarda en inicializarse (conexiones a base de datos, calentamiento de caché, etc.).
- `max_restarts` — número máximo de intentos de reinicio dentro de una ventana de tiempo. Por defecto: `15`. Si tu app falla 15 veces en 15 minutos, PM2 deja de intentarlo y la marca como errored. Esto evita bucles de reinicio infinitos.

**Estrategias avanzadas**:

```sh
# Backoff exponencial — evita el thundering herd en caídas de la BD
pm2 start app.js --exp-backoff-restart-delay 100

# Omite el reinicio automático para códigos de salida concretos (p. ej., apagado limpio)
pm2 start app.js --stop-exit-codes 0

# Reinicio basado en cron (reinicia cada día a medianoche)
pm2 start app.js --cron-restart "0 0 * * *"

# Retardo fijo entre reinicios (5 segundos)
pm2 start app.js --restart-delay 5000
```

El backoff exponencial es especialmente útil cuando tu app depende de una base de datos o un servicio externo que puede estar temporalmente no disponible. En lugar de machacarlo con reinicios, PM2 retrocede exponencialmente.

### Persistencia de apps tras reinicios con `pm2 startup`

Esto es lo que hace a PM2 práctico para producción. Sin esto, tus apps mueren cuando el servidor se reinicia y tienes que entrar por SSH y reiniciarlo todo manualmente.

```sh
pm2 startup
pm2 save
```

`pm2 startup` genera un servicio systemd que arranca PM2 en el boot. `pm2 save` guarda una instantánea de la lista de procesos actual en `~/.pm2/dump.pm2` para que PM2 sepa qué restaurar al arrancar.

Para un usuario diferente:

```sh
sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u your_user --hp /home/your_user
```

<Notice type="warning" title="¿Las apps no sobreviven al reinicio?">
Debes ejecutar TANTO `pm2 startup` COMO `pm2 save`. Si falta cualquiera de los dos, los procesos no se restaurarán. Verifica con: `systemctl status pm2-<user>`.
</Notice>

**¿Actualizando Node.js?** Ejecuta `pm2 unstartup` antes de actualizar, y después `pm2 startup` + `pm2 save` otra vez. Si no, el servicio systemd apuntará al binario antiguo de Node.js.

`pm2 save --force` te permite guardar una lista de procesos vacía. Útil para restablecer el estado de arranque.

## Funciones avanzadas de PM2

### Configuración ecosystem multi-app

Puedes gestionar varias apps en un solo `ecosystem.config.js`. Ahí está el verdadero poder de los archivos ecosystem. Un comando para arrancar, parar o recargar todo. El ejemplo de Streamlit de antes muestra este patrón. Añade tantos objetos de app al array `apps` como necesites:

```js
module.exports = {
  apps: [
    { name: "api", script: "./api.js", instances: "max", exec_mode: "cluster" },
    { name: "worker", script: "./worker.py", interpreter: "python3", instances: 1 },
    { name: "scheduler", script: "./cron.js", cron_restart: "0 * * * *" }
  ]
}
```

Arranca todas las apps: `pm2 start ecosystem.config.js`

Arranca solo una app por nombre: `pm2 start ecosystem.config.js --only api`

### Servir archivos estáticos con `pm2 serve`

PM2 puede servir archivos estáticos sin un servidor web aparte como Nginx o Caddy. Es útil para SPAs, sitios de documentación o cualquier salida de build estática:

```sh
# Servidor básico de archivos estáticos
pm2 serve /path/to/build 3000 --name my-spa --spa

# Listado de directorios (v7.0.0+)
pm2 serve /path/to/files 8080 --ftp
```

El flag `--spa` redirige todos los 404 a `index.html` para aplicaciones de una sola página. El flag `--ftp` (nuevo en v7.0.0) activa el listado de directorios, similar al `http.server` de Python.

Esto está bien para desarrollo o herramientas internas, pero para tráfico de producción normalmente pondrías Nginx o Caddy delante como proxy inverso con terminación TLS.

### PM2 en Docker con `pm2-runtime`

`pm2-runtime` es un sustituto directo de `node` diseñado para contenedores. Gestiona el apagado graceful (reenvío de SIGINT) y el formato de logs adecuado:

```dockerfile
CMD ["pm2-runtime", "ecosystem.config.js"]
```

También puedes pasar opciones de formato de log:

```sh
pm2-runtime ecosystem.config.js --json     # Salida de logs en JSON
pm2-runtime ecosystem.config.js --raw      # Salida sin formato (sin timestamps)
```

¿Por qué usar PM2 dentro de Docker? Clustering en contenedores multinúcleo, reinicios graceful y un formato de logs consistente. Si ejecutas contenedores de un solo proceso con las políticas de reinicio de Docker, probablemente no necesitas PM2 — pero para contenedores multinúcleo o apps que se benefician de las estrategias de reinicio de PM2, es útil. La principal ventaja frente a `restart: always` de Docker es que PM2 puede hacer backoff exponencial, reinicios basados en memoria y modo cluster — la política de reinicio de Docker simplemente reinicia a ciegas.

Para más sobre apps Python en contenedores, consulta [ejecutar apps Python en Docker](/es/docker-ejecutar-python/).

### Namespaces para agrupar procesos

Los namespaces te permiten agrupar procesos relacionados y ver sus logs juntos:

```sh
pm2 start app.js --namespace api
pm2 start worker.js --namespace workers
pm2 start scheduler.js --namespace workers
pm2 logs api          # Ver los logs de todos los procesos "api"
pm2 logs workers      # Ver los logs de todos los procesos "workers"
```

Es más limpio que gestionar nombres de proceso individualmente cuando tienes muchas apps en el mismo servidor.

### Trazado con OpenTelemetry (v7.0+)

PM2 v7 incluye `@opentelemetry/api` y `@opentelemetry/sdk-node` como dependencias directas. Esto habilita el trazado distribuido para apps Node.js, aunque la integración todavía requiere configuración con un backend colector (Jaeger, Grafana Tempo, etc.). La dependencia viene incluida — no necesitas instalarla aparte — pero tendrás que configurar el colector y la instrumentación para tu framework concreto. Es una función relativamente nueva y la documentación aún está evolucionando.

## Solución de problemas comunes de PM2

<Accordion label="El daemon de PM2 no arranca" group="pm2-troubleshooting">

Comprueba tu versión de Node.js — PM2 v7.x requiere Node.js >= 18.0.0. Ejecuta `node --version` para verificar. Si Node.js está bien, prueba a matar el daemon y reiniciar:

```sh
pm2 kill
pm2 start app.js
```

Si usas nvm, asegúrate de que la versión correcta de Node está activa en tu sesión de shell actual.

</Accordion>

<Accordion label="Las apps no sobreviven al reinicio" group="pm2-troubleshooting">

Verifica que ejecutaste AMBOS comandos:

```sh
pm2 startup    # Crea el servicio systemd
pm2 save       # Guarda la lista de procesos
```

Comprueba el servicio systemd:

```sh
systemctl status pm2-$(whoami)
```

Si el servicio no existe o apunta al binario equivocado de Node.js, ejecuta `pm2 unstartup` y después `pm2 startup` + `pm2 save` otra vez.

</Accordion>

<Accordion label="Los logs llenan el disco" group="pm2-troubleshooting">

Instala el módulo pm2-logrotate (ver la [sección de gestión de logs](#instalación-y-configuración-de-pm2-logrotate)):

```sh
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 30
pm2 set pm2-logrotate:compress true
```

Para vaciar los logs inmediatamente: `pm2 flush`

</Accordion>

<Accordion label="pm2 ls muestra un usuario incorrecto o datos desactualizados" group="pm2-troubleshooting">

Refresca el daemon:

```sh
pm2 update
```

Si eso no ayuda:

```sh
pm2 kill
pm2 resurrect
```

</Accordion>

<Accordion label="Actualizar Node.js rompe PM2" group="pm2-troubleshooting">

El script de arranque de systemd apunta a un binario concreto de Node.js. Antes de actualizar:

```sh
pm2 unstartup
# actualiza Node.js aquí
pm2 startup
pm2 save
```

</Accordion>

<Accordion label="Cambiar entre Node.js y Bun" group="pm2-troubleshooting">

El daemon de PM2 conserva su runtime. Tienes que matarlo primero:

```sh
pm2 kill
pm2 start app.ts    # Ahora usa Bun si está instalado
```

</Accordion>

## PM2 vs alternativas: cuándo usarlo

PM2 no es la única forma de gestionar procesos en un servidor Linux. Aquí va una valoración honesta de cuándo tiene sentido y cuándo deberías mirar otras opciones.

<Tabs>
<Tab name="Usa PM2 cuando">
- Ejecutas varias apps Node.js, Bun o Python en un solo VPS
- Necesitas clustering con balanceo de carga en una máquina sin escribir código de cluster
- Quieres un panel de monitorización rápido (`pm2 monit`) sin montar Grafana ni similares
- Estás prototipando o ejecutando un stack de producción pequeño-mediano en un VPS económico
- Quieres `pm2 startup` + `pm2 save` para persistencia tras reinicios sin escribir unidades systemd
- Necesitas rotación de logs sencilla, reinicios por memoria y reinicios por cron listos para usar
</Tab>
<Tab name="Prescinde de PM2 cuando">
- Ya usas Docker o Kubernetes con políticas de reinicio — PM2 añade una capa innecesaria
- Ejecutas contenedores de un solo proceso (Docker gestiona los reinicios nativamente con `restart: always`)
- Prefieres systemd por simplicidad y no necesitas clustering ni el panel de monitorización
- Necesitas aislamiento de procesos — los procesos de PM2 comparten el mismo sistema de archivos y usuario
- Despliegas a través de un [panel de servidor autoalojado](/es/mejores-paneles-autoalojados/) como Coolify, Dokploy o CloudPanel que gestiona los procesos por ti
</Tab>
</Tabs>

Systemd es el otro enfoque habitual para la persistencia tras el arranque y el reinicio automático en Linux. Es más verboso (escribes un archivo `.service` para cada app), pero viene integrado en todas las distros Linux y no tiene dependencia de runtime. Si solo tienes una app y no necesitas clustering, systemd es más simple y predecible. PM2 se gana su sitio cuando tienes varias apps, quieres el modo cluster o necesitas el panel de monitorización.

Para quienes despliegan Node.js a través de un panel, consulta [desplegar apps Node.js con CloudPanel y PM2](/es/instalar-cloudpanel-alojar-nodejs/) para un enfoque combinado.

<Notice type="info" title="Licencia AGPL 3.0">
PM2 está licenciado bajo AGPL 3.0. Esto está bien para uso interno y para ejecutar tus propias apps. Si vas a integrar PM2 en un producto comercial o a distribuirlo como parte de un servicio, revisa los términos de la licencia.
</Notice>

## Conclusión

PM2 es un gestor de procesos sólido y probado en batalla que cubre la mayor parte de lo que necesitas para ejecutar apps en producción en un solo VPS: reinicios automáticos, clustering, gestión de logs, monitorización y persistencia tras el arranque. Empieza con `pm2 init simple` para generar un archivo de configuración ecosystem, usa el modo cluster para apps Node.js que se beneficien de varios núcleos, y configura pm2-logrotate pronto — antes de que se te llene el disco.

La versión 7.x hizo que PM2 también sea relevante para proyectos Bun, y el diseño mejorado de la CLI hace el uso diario más agradable. No sustituye a una orquestación de contenedores en condiciones si gestionas una flota de servicios, pero para un operador en solitario que administra un puñado de apps en un VPS, hace bien su trabajo.

## Preguntas frecuentes

<Accordion label="¿Para qué sirve el gestor de procesos PM2?" group="pm2-faq">

PM2 ejecuta apps Node.js, Python y Bun en producción como daemons en segundo plano. Gestiona el reinicio automático tras fallos, clustering con balanceo de carga, gestión de logs, monitorización y persistencia tras los reinicios del servidor. Piensa en él como un supervisor de procesos ligero: mantiene tus apps funcionando incluso cuando las cosas van mal.

</Accordion>

<Accordion label="¿PM2 soporta Bun?" group="pm2-faq">

Sí. PM2 v7.x tiene soporte nativo para Bun. Los archivos TypeScript (`.ts`, `.tsx`) detectan Bun automáticamente cuando está instalado. Para el modo cluster con Bun, necesitas Bun >= 1.1.25 y debes arrancar con `bunx --bun pm2 start app.ts -i max`. Ten en cuenta que el daemon de PM2 conserva su runtime: si cambias de Node.js a Bun, tienes que ejecutar `pm2 kill` primero.

</Accordion>

<Accordion label="¿Cuál es la diferencia entre el modo fork y el modo cluster de PM2?" group="pm2-faq">

El modo fork (el predeterminado) ejecuta un proceso por app en un proceso hijo aislado. El modo cluster ejecuta varias instancias de tu app repartidas entre todos los núcleos de CPU con balanceo de carga automático usando el módulo `cluster` integrado de Node.js. El modo cluster solo funciona con Node.js y Bun — no con Python, debido al Global Interpreter Lock (GIL). Para apps Python, usa el modo fork con varias instancias si necesitas paralelismo.

</Accordion>

<Accordion label="¿Cómo actualizo PM2?" group="pm2-faq">

```sh
npm install pm2@latest -g
pm2 update
```

`pm2 update` es la parte importante: guarda la lista de procesos, mata el daemon antiguo y restaura todo con la nueva versión. Ejecutar solo `npm install` deja un daemon obsoleto corriendo el código viejo. Usa siempre `pm2 update` después de actualizar.

</Accordion>

<Accordion label="¿PM2 funciona en Docker?" group="pm2-faq">

Sí. Usa `pm2-runtime` en lugar de `pm2` en tu Dockerfile. Está diseñado para entornos de contenedores con el reenvío de señales adecuado (SIGINT/SIGTERM) y formato de logs:

```dockerfile
CMD ["pm2-runtime", "ecosystem.config.js"]
```

`pm2-runtime` se ejecuta en primer plano (no se daemoniza), que es lo que esperan los contenedores. Obtienes el clustering y las estrategias de reinicio de PM2 dentro del contenedor, además de una salida de logs estructurada que Docker puede recoger.

</Accordion>