Gestão de Processos com PM2
Guia completo de gestão de processos com PM2 no Linux: instalação, configuração, cluster mode, monitorização e manutenção.
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.
O que é o PM2?
PM2 é um daemon (processo em background) que gere 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
Ou se usas Yarn:
yarn global add pm2
Depois de instalado, confirma que está tudo certo:
pm2 --version
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
Isto diz ao PM2 para:
- Executar o ficheiro
- Daemonizar (correr em background)
- 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 (restart automático se alterares o código)
pm2 start bot.py --watch
# Binário compilado com argumentos extra
pm2 start ./meu-binary -- --port 1520 --config prod
Opções úteis no arranque
pm2 start app.js \
--name "minha-api" \
--watch \
--max-memory-restart 200M \
--log /var/log/app.log \
--time \
--restart-delay 3000 \
--cron-restart "0 4 * * *"
--name— nome amigável do processo--watch— reinicia quando os ficheiros mudam (útil em desenvolvimento, não em produção)--max-memory-restart 200M— reinicia se a memória passar os 200 MB--log— caminho do ficheiro de log--time— prefixa cada linha do log com a data e a hora--restart-delay 3000— espera 3 s antes de reiniciar--cron-restart "0 4 * * *"— reinício forçado todos os dias às 4h
Existe ainda o --no-autorestart, para o PM2 não reiniciar o processo quando este cai.
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,
},
node_args: "--env-file=.env", // carrega o .env (Node 20.6 ou superior)
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, // reinícios instáveis seguidos antes de ficar "errored"
restart_delay: 5000, // espera 5s entre restarts
},
{
name: "bot-worker",
script: "workers/bot.py",
interpreter: "python3",
instances: 1,
exec_mode: "fork",
},
],
};
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
Isto é muito mais reproduzível e versionável que dezenas de flags na CLI.
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
Podes usar all para atuar em todos os processos:
pm2 restart all
pm2 stop all
Ou usar o ID do processo (vê no pm2 list):
pm2 stop 0
pm2 delete 3
Monitorização — Vê o que se Passa
Listar processos
pm2 list
# ou
pm2 ls
# ou
pm2 status
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
Dashboard no terminal
pm2 monit
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
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
No ecosystem file:
{
name: "api",
script: "app.js",
instances: "max",
exec_mode: "cluster",
}
Nota: O
pm2 reloadem 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, base de dados). Cada instância é um processo independente.
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
O pm2 startup deteta o teu init system (systemd, launchd, etc.) e imprime um comando que tens de copiar e correr (começa por sudo env PATH=…): é esse comando que cria o serviço de arranque. Corre o pm2 startup sem sudo e depois o comando que ele mostrar. O pm2 save guarda a lista de processos ativos.
Quando o servidor reiniciar, o PM2 restaura automaticamente todos os processos.
# Desativar (se deixares de usar PM2)
pm2 unstartup
Log Rotation — Logs Não Enchem o Disco
Por defeito, o PM2 escreve logs para ficheiros que podem crescer sem limite. Usa o módulo de log rotation:
pm2 install pm2-logrotate
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)
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:
// Numa app Node.js
process.on("SIGINT", () => {
console.log("A encerrar graciosamente...");
server.close(() => {
// Fechar ligações à BD
// Terminar workers
process.exit(0);
});
});
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"
}
Resumo de Comandos Úteis
| Comando | O que faz |
|---|---|
pm2 list |
Lista processos |
pm2 start app.js |
Inicia app |
pm2 start ecosystem.config.js |
Inicia config |
pm2 stop app |
Para processo |
pm2 restart app |
Reinicia |
pm2 reload app |
Zero-downtime reload |
pm2 delete app |
Remove do PM2 |
pm2 logs |
Logs em tempo real |
pm2 monit |
Dashboard terminal |
pm2 show app |
Detalhes do processo |
pm2 startup |
Auto-arranque no boot |
pm2 save |
Guarda lista de processos |
pm2 status |
Estado 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:
- Cria um
ecosystem.config.jsno teu projeto atual - Testa o cluster mode (
-i max) - Configura o
pm2 startuppara persistência - Instala o
pm2-logrotatese 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
Partilhar
Comentários 0
Ainda sem comentários — sê o primeiro.