Já te aconteceu uma aplicação Node.js cair em produção às 3 da manhã e só dares por isso no dia seguinte? Ou teres um bot em Python que precisa de estar sempre online mas não sabes como o manter vivo?

É aqui que entra o PM2 (Process Manager 2).

O PM2 é um gestor de processos para Node.js (e não só) que mantém as tuas aplicações online 24/7. Ele faz o auto-restart quando algo falha, gere logs, expõe métricas e ainda permite escalar em cluster com poucos comandos.

Neste artigo, vou mostrar-te como usar o PM2 no dia-a-dia: desde o básico até configurações de produção que uso nos meus próprios servidores.


O que é o pm2?

PM2 é um daemon (processo em background) que gerencia as tuas aplicações. Podes pensar nele como um systemd para as tuas apps Node.js, mas mais simples e com features específicas para developers.

Porquê PM2 em vez de...

Alternativa Quando usar
systemd Quando queres integração profunda com o SO. Mas é mais verboso
screen/tmux Fixe para sessões ad-hoc, mas não faz auto-restart
Docker Excelente para ambientes isolados. Mas PM2 é mais leve para uma app simples
nohup & Funcional, mas zero monitorização

PM2 dá-te o meio-termo: simples de configurar, com monitorização, restart automático e logs.

Instalação

Instalar é direto com npm:

npm install pm2@latest -g
Copy

Ou se usas Yarn:

yarn global add pm2
Copy

Depois de instalado, confirma que está tudo certo:

pm2 --version
Copy

Dica: Se ainda não tens Node.js instalado, usa o NVM (Node Version Manager). É a forma mais limpa de gerir versões do Node.

Primeiros passos: iniciar uma aplicação

A forma mais simples de começar:

pm2 start app.js
Copy

Isto diz ao PM2 para:

  1. Executar o ficheiro
  2. Daemonizar (correr em background)
  3. Monitorizar e fazer restart se cair

Mas o PM2 não se limita a Node.js. Consegues gerir qualquer tipo de processo:

# Script bash
pm2 start backup.sh

# App Python com watch mode
pm2 start bot.py --watch

# Binário compilado com argumentos extra
pm2 start ./meu-binary -- --port 1520 --config prod
Copy
Opções úteis no arranque
pm2 start app.js \
  --name "minha-api"              # Nome amigável
  --watch                          # Restart automático quando alteras ficheiros
  --max-memory-restart 200M        # Restart se memória exceder 200MB
  --log /var/log/app.log           # Caminho do log
  --time                           # Prefixa as linhas do log com timestamp
  --restart-delay 3000             # Espera 3s antes de restart
  --no-autorestart                 # Não faz restart automático
  --cron "0 4 * * *"               # Faz restart forçado todos os dias às 4h
Copy

Ecosystem file: a configuração a sério

Linha de comandos é fixe para testes. Mas em produção vais querer um ficheiro de configuração declarativa.

Cria um ficheiro ecosystem.config.js na raiz do projeto:

module.exports = {
  apps: [
    {
      name: "api-prod",
      script: "dist/server.js",
      instances: "max",          // cluster mode (usa todos os CPUs)
      exec_mode: "cluster",
      env: {
        NODE_ENV: "production",
        PORT: 3000,
      },
      env_file: ".env",
      max_memory_restart: "300M",
      log_date_format: "YYYY-MM-DD HH:mm:ss",
      error_file: "./logs/err.log",
      out_file: "./logs/out.log",
      merge_logs: true,
      autorestart: true,
      watch: false,
      max_restarts: 10,           // max restarts em 60s
      restart_delay: 5000,        // espera 5s entre restarts
    },
    {
      name: "bot-worker",
      script: "workers/bot.py",
      interpreter: "python3",
      instances: 1,
      exec_mode: "fork",
    },
  ],
};
Copy

Depois é só:

# Iniciar todas as apps do ficheiro
pm2 start ecosystem.config.js

# Apenas uma app específica
pm2 start ecosystem.config.js --only api-prod
Copy

Isto é muito mais reproduzível e versionável que dezenas de flags na CLI.

CLI vs Ecosystem File - comparação

⬆ Comparação: comandos soltos na CLI vs ecosystem file declarativo

Gestão de processos

Comandos básicos do dia-a-dia:

pm2 restart api-prod          # Reinicia a app
pm2 reload api-prod           # Reload com zero downtime (cluster mode)
pm2 stop api-prod             # Para a app (mas mantém no PM2)
pm2 delete api-prod           # Remove do PM2 por completo
Copy

Podes usar all para atuar em todos os processos:

pm2 restart all
pm2 stop all
Copy

Ou usar o ID do processo (vê no pm2 list):

pm2 stop 0
pm2 delete 3
Copy

Monitorização: vê o que se passa

Listar processos
pm2 list
# ou
pm2 ls
# ou
pm2 status
Copy

pm2 list - terminal screenshot

⬆ Processos reais no servidor fuzzalab.pt (37.187.127.161)

Vês o nome, ID, estado (online/stopped/errored), uso de CPU/memória, e há quanto tempo está ativo.

Logs em tempo real
pm2 logs                    # Logs de todas as apps
pm2 logs api-prod           # Logs de uma app específica
pm2 logs --lines 200        # Últimas 200 linhas
Copy
Dashboard no terminal
pm2 monit
Copy

pm2 monit - dashboard em tempo real

⬆ Dashboard PM2 com processos, detalhes, CPU, memória e logs

Isto dá-te um htop-like com CPU, memória, e logs por processo. Uso isto constantemente quando estou a debuggar alguma coisa.

Informação detalhada
pm2 show api-prod
Copy

Mostra versão do Node, path, variáveis de ambiente, tempo de atividade, restarts.

Cluster mode: escalar para todos os cpus

Uma das melhores features do PM2: cluster mode.

Em vez de correr uma única instância do Node.js (que é single-threaded), o PM2 cria várias instâncias: uma por CPU: e faz load balancing entre elas.

# Usando todos os CPUs
pm2 start app.js -i max

# Ou um número específico
pm2 start app.js -i 4
Copy

No ecosystem file:

{
  name: "api",
  script: "app.js",
  instances: "max",
  exec_mode: "cluster",
}
Copy

Nota: O pm2 reload em cluster mode faz zero-downtime restart. Ele reinicia as instâncias uma de cada vez, garantindo que há sempre processos a responder a pedidos.

Se a tua app mantém estado em memória (sessions, etc.), precisas de um mecanismo partilhado (Redis, banco de dados). Cada instância é um processo independente.

Cluster Mode - diagrama de arquitetura

⬆ Arquitetura do cluster mode: load balancer distribui pedidos pelas várias instâncias

Startup & persistência: manter vivo após reboot

Um dos maiores problemas de usar node app.js diretamente: quando o servidor reinicia, a aplicação morre.

O PM2 resolve isto com o sistema startup:

# Gerar script de auto-arranque
pm2 startup

# Guardar o estado atual dos processos
pm2 save
Copy

O pm2 startup deteta o teu init system (systemd, upstart, launchd) e gera o script apropriado. O pm2 save guarda a lista de processos ativos.

Quando o servidor reiniciar, o PM2 restaura automaticamente todos os processos.

# Ver a configuração de startup
pm2 startup info

# Desativar (se deixares de usar PM2)
pm2 unstartup
Copy

Log rotation: logs não enchem o disco

Por defeito, o PM2 escreve logs para ficheiros que podem crescer até ocupar TBs. Usa o módulo de log rotation:

pm2 install pm2-logrotate
Copy

Configuração (via PM2):

pm2 set pm2-logrotate:max_size 10M      # Rotação quando chega a 10MB
pm2 set pm2-logrotate:retain 7           # Manter 7 ficheiros de log
pm2 set pm2-logrotate:compress true      # Comprimir logs antigos (gzip)
Copy

Isto é obrigatório em produção. Acredita, não queres descobrir que /var/log está cheio às 3 da manhã.

Graceful shutdown: parar sem partir tudo

Quando o PM2 faz restart, ele envia um sinal SIGINT ao processo. A tua app deve apanhar esse sinal e fazer cleanup:

process.on("SIGINT", () => {
  console.log("A encerrar graciosamente...");
  server.close(() => {
    // Fechar ligações à BD
    // Terminar workers
    process.exit(0);
  });
});
Copy

Graceful Shutdown - fluxo completo

⬆ Fluxo do graceful shutdown: SIGINT → cleanup → exit → restart

No ecosystem file, podes configurar:

{
  name: "api",
  script: "app.js",
  kill_timeout: 5000,          // timeout para graceful shutdown (5s)
  listen_timeout: 3000,        // tempo a esperar que a app fique "ready"
}
Copy

Resumo de comandos úteis

Comando O que faz
pm2 listLista processos
pm2 start app.jsInicia app
pm2 start ecosystem.config.jsInicia config
pm2 stop appPara processo
pm2 restart appReinicia
pm2 reload appZero-downtime reload
pm2 delete appRemove do PM2
pm2 logsLogs em tempo real
pm2 monitDashboard terminal
pm2 show appDetalhes do processo
pm2 startupAuto-arranque no boot
pm2 saveGuarda lista de processos
pm2 statusEstado dos processos

Conclusão

O PM2 é uma ferramenta que uso em todos os meus servidores. Não é só para Node.js: já o usei para gerir bots Python, scripts bash, e até binários Go.

A beleza está na simplicidade: com pm2 start tens uma app monitorizada e persistente. Com ecosystem.config.js tens uma configuração reproduzível e versionável.

Próximos passos que recomendo:

  1. Cria um ecosystem.config.js no teu projeto atual
  2. Testa o cluster mode (-i max)
  3. Configura o pm2 startup para persistência
  4. Instala o pm2-logrotate se fores usar em produção

Já usas PM2? Ou preferes outra abordagem? Deixa um comentário ou manda mensagem: gosto de saber como outros developers resolvem estes problemas.

Recursos

Comentários (0)

Nenhum comentário ainda. Seja o primeiro!

Deixar comentário