PM2: Como Rodar Aplicações Node.js em Produção
Aprenda a usar PM2 com Node.js em produção: ecosystem, startup, cluster, reload sem downtime, logs, limites de memória, Nginx e deploy seguro.

PM2 é um gerenciador de processos que mantém aplicações Node.js executando em segundo plano, reinicia processos após falhas, organiza configuração e logs e pode distribuir uma aplicação de rede entre vários núcleos.
Em uma VPS, ele resolve a camada entre “rodar node app.js no terminal” e operar um serviço continuamente.
Usar PM2 em produção exige mais que instalar o pacote e executar pm2 start.
É preciso definir usuário, diretório, variáveis, política de reinício, inicialização no boot, limites, encerramento gracioso, rotação de logs, proxy reverso e um processo seguro de deploy.
Neste guia, você montará essa estrutura passo a passo e entenderá quando usar modo fork ou cluster, restart ou reload e PM2 ou outra camada de execução.
O foco é uma API ou aplicação Node.js em servidor Linux, sem transformar o PM2 em substituto de monitoramento, backup ou segurança do sistema.
O que é PM2 e quando usar
PM2 executa um daemon sob um usuário do sistema e mantém uma lista de processos gerenciados.
A aplicação continua ativa após o encerramento da sessão SSH, pode ser reiniciada quando falha e recebe comandos padronizados de start, stop, restart, reload, logs e inspeção.
Ele é especialmente útil quando você publica Node.js diretamente em uma VPS ou máquina virtual e quer administrar uma ou várias APIs, workers e aplicações sem construir essa camada do zero.
A documentação oficial de início rápido do PM2 apresenta esse fluxo básico.
Para quem ainda está escolhendo infraestrutura, o comparativo entre VPS e hospedagem compartilhada explica por que uma aplicação Node.js persistente normalmente exige mais controle do servidor.
O que o PM2 faz — e o que não faz
- mantém processos em segundo plano e reinicia falhas;
- nomeia e administra várias aplicações;
- centraliza opções no arquivo de ecossistema;
- restaura uma lista salva após reboot;
- expõe consumo de CPU e memória;
- organiza saída padrão e erros em arquivos;
- distribui aplicações de rede em cluster;
- realiza reload gradual quando a aplicação permite.
PM2 não configura firewall, TLS, DNS ou backups; não substitui proxy reverso; não corrige vazamento de memória; não transforma uma aplicação stateful em escalável; e não oferece sozinho observabilidade distribuída. Reiniciar um processo mascara o sintoma, mas a causa ainda precisa ser investigada.
Prepare o servidor antes de instalar
Crie um usuário de deploy sem privilégios de root, mantenha o sistema atualizado e instale uma versão suportada do Node.js. Confirme com node --version e npm --version.
A versão usada no shell deve ser a mesma encontrada pelo serviço de inicialização.
Defina um diretório estável, como /var/www/minha-api/current, com propriedade correta.
A aplicação deve aceitar porta por variável, encerrar conexões ao receber sinal e expor uma verificação de saúde. Não publique banco, Redis ou a porta do Node.js diretamente na internet sem necessidade.
Como instalar e atualizar o PM2
npm install pm2@latest --global pm2 --version
Instale com o usuário que administrará a aplicação. Não alterne entre root e usuário comum: cada usuário tem seu próprio diretório ~/.pm2, lista de processos, sockets, logs e serviço de startup.
Executar comandos com usuários diferentes é uma causa frequente de “processo desaparecido”.
Para atualizar, instale a versão desejada e execute pm2 update para atualizar o daemon em memória.
Faça isso em janela controlada, valide compatibilidade e teste a aplicação; “latest” é conveniente na instalação inicial, mas produção pede versão e processo de mudança conhecidos.
Inicie a primeira aplicação
cd /var/www/minha-api/current pm2 start dist/server.js --name minha-api pm2 status pm2 logs minha-api --lines 100
Use o arquivo realmente executado em produção. Projetos TypeScript geralmente compilam para dist; iniciar o código-fonte com ferramenta de desenvolvimento acrescenta dependências e comportamento desnecessários.
Se o projeto usa script do package.json, também é possível executar pm2 start npm --name minha-api -- start.
Faça primeiro uma execução simples em modo fork. Verifique rota de saúde, conectividade com dependências, logs, uso de memória e resposta atrás do proxy. Cluster deve ser uma decisão posterior, não uma tentativa de consertar uma instância que ainda falha.
Comandos essenciais do PM2
| Comando | Finalidade |
|---|---|
pm2 status | Lista processos, estado, reinícios, CPU e memória. |
pm2 show minha-api | Exibe configuração, caminhos, ambiente e histórico. |
pm2 logs minha-api | Acompanha saída e erros do processo. |
pm2 monit | Abre painel de terminal com métricas básicas. |
pm2 restart minha-api | Encerra e inicia novamente. |
pm2 reload minha-api | Faz troca gradual quando o modo suporta. |
pm2 stop minha-api | Interrompe sem remover da lista. |
pm2 delete minha-api | Interrompe e remove da lista gerenciada. |
pm2 save | Salva a lista para restauração no boot. |
pm2 resurrect | Restaura manualmente a lista salva. |
Prefira o nome estável ao ID numérico, pois IDs mudam quando processos são recriados. Depois de qualquer mudança, consulte pm2 status, logs e uma rota real; a resposta de um comando não prova que a aplicação está saudável.
Arquivo ecosystem.config.js
Comandos manuais são úteis para aprender, mas não formam uma configuração reproduzível.
O arquivo ecosystem.config.js registra nome, script, diretório, instâncias, ambiente, limites e timeouts. A documentação do Ecosystem File reúne os atributos aceitos.
Exemplo de configuração para produção
module.exports = {
apps: [{
name: 'minha-api',
cwd: '/var/www/minha-api/current',
script: 'dist/server.js',
instances: 2,
exec_mode: 'cluster',
autorestart: true,
max_memory_restart: '500M',
restart_delay: 3000,
max_restarts: 10,
min_uptime: '10s',
wait_ready: true,
listen_timeout: 10000,
kill_timeout: 10000,
time: true,
env_production: {
NODE_ENV: 'production',
PORT: 3000
}
}]
};
Inicie com pm2 start ecosystem.config.js --env production. Ajuste números ao comportamento medido; um limite de memória copiado sem observar a aplicação pode provocar reinícios normais ou permitir que o servidor fique sem memória.

Variáveis de ambiente e segredos
O bloco env_production serve para configurações não sensíveis e para declarar quais valores a aplicação espera. Evite commitar senhas, tokens e chaves no arquivo de ecossistema. Injete segredos pelo ambiente do servidor, arquivo protegido fora do repositório ou serviço de gerenciamento.
Ao mudar variáveis de um processo em execução, reinicie ou recarregue com o ambiente atualizado conforme o fluxo adotado. Confirme pelo comportamento, sem imprimir valores sensíveis.
O guia de Dotenv e variáveis de ambiente aprofunda precedência, validação e cuidados em produção.
Inicialização automática após reboot
autorestart lida com a falha da aplicação enquanto o daemon está ativo. Para sobreviver ao reboot da máquina, integre PM2 ao sistema de inicialização e salve a lista.
A documentação de Startup Script detalha sistemas como systemd.
pm2 startup # execute exatamente o comando com sudo mostrado pelo PM2 pm2 save systemctl status pm2-SEU_USUARIO
Execute pm2 startup sem sudo e copie o comando que ele gerar, pois esse comando inclui usuário, home e caminho do Node.js. Depois de adicionar ou remover aplicações, rode pm2 save novamente. Sem isso, o boot restaura uma lista antiga.
Teste de verdade: reinicie a máquina em janela planejada, aguarde o sistema e verifique serviço, lista, logs e URL externa. Se você atualizou Node.js via gerenciador de versões, recrie o startup para apontar ao binário correto.
Modo fork ou cluster
No modo fork, PM2 executa uma instância independente. Ele serve para workers, tarefas agendadas e aplicações que não devem compartilhar uma porta.
Também é o começo mais simples para validar uma API. Vários processos em fork precisam de portas diferentes ou responsabilidades distintas.
No modo cluster, PM2 inicia várias instâncias de uma aplicação Node.js de rede que compartilham a mesma porta por meio do cluster do Node. A documentação oficial do Cluster Mode explica o balanceamento e o reload gradual.
| Modo | Quando usar | Principal cuidado |
|---|---|---|
| Fork | Uma instância, worker, bot ou tarefa. | Não utiliza vários núcleos no mesmo processo. |
| Cluster | API HTTP/TCP/UDP com múltiplas instâncias. | Estado local não é compartilhado entre workers. |
Como escalar processos em cluster
Você pode definir uma quantidade explícita ou usar instances: 'max'. “Máximo” não significa “melhor”: banco, memória, filas e carga real determinam o número útil.
Em uma VPS pequena, deixar CPU e memória para proxy, sistema e serviços auxiliares evita saturação.
pm2 start ecosystem.config.js --env production pm2 scale minha-api 4 pm2 status
Sessões em memória, caches locais, filas internas e locks deixam de ser confiáveis entre instâncias. Mova estado compartilhado para banco, Redis ou outro serviço adequado.
WebSockets podem exigir adaptador e estratégia de distribuição; teste reconexão e entrega antes de escalar.
Restart, reload e zero downtime
restart encerra o processo e inicia outro, criando uma interrupção enquanto a instância volta. reload em cluster sobe novos workers antes de retirar os antigos. Se o reload não for concluído dentro do tempo, PM2 pode voltar ao restart tradicional.
Zero downtime é uma propriedade do sistema, não só do comando. A nova versão precisa iniciar corretamente, ficar pronta antes de receber tráfego e ser compatível com banco, filas e clientes.
Uma migração destrutiva ou um processo que aceita conexão antes de carregar dependências ainda provoca falhas.
pm2 reload ecosystem.config.js --only minha-api --env production pm2 status pm2 logs minha-api --lines 100
Encerramento gracioso
Ao recarregar, PM2 envia inicialmente SIGINT. A aplicação deve parar de aceitar novas conexões, permitir que requisições em andamento terminem, fechar banco, filas e consumidores e então sair.
Se ignorar o sinal, o processo pode ser morto ao atingir kill_timeout.
process.on('SIGINT', async () => {
server.close(async () => {
await database.close();
process.exit(0);
});
});
Adicione um limite próprio para não aguardar indefinidamente e trate sinais também em testes.
Encerramento gracioso não garante que toda tarefa longa terminará; trabalhos recuperáveis precisam de confirmação, reentrega ou checkpoint.
Sinal de prontidão e timeouts
Com wait_ready: true, a aplicação informa quando terminou de inicializar usando process.send('ready'). Isso é melhor que considerar o processo saudável apenas porque foi criado.
Em cluster, a nova instância deve carregar configuração, validar dependências essenciais e começar a escutar antes de substituir a antiga.
server.listen(port, () => {
if (process.send) process.send('ready');
});
listen_timeout limita a espera pelo estado pronto; kill_timeout limita a finalização. Valores curtos demais derrubam inicializações normais, e longos demais prolongam deploys com falha.
Meça os tempos reais e mantenha uma rota de saúde para validação externa.
Memória e política de reinício
max_memory_restart reinicia a aplicação ao ultrapassar um limite, protegendo o host de crescimento descontrolado. Isso é uma contenção, não correção de vazamento. Monitore tendência, heap, carga e eventos que antecedem o crescimento.
restart_delay evita repetição instantânea; min_uptime define quanto tempo caracteriza uma inicialização estável; max_restarts interrompe o ciclo após falhas sucessivas. Sem limites, uma configuração inválida pode gerar crash loop, consumir CPU e encher logs.
Investigue a causa com stack trace sanitizado, versão implantada, variáveis esperadas e dependências. O guia sobre depuração de aplicações Node.js complementa esse diagnóstico.
Logs e rotação
PM2 separa saída padrão e erro e permite acompanhar com pm2 logs. A documentação de gerenciamento de logs mostra filtros, formato, caminhos e rotação.
pm2 logs minha-api --lines 200 pm2 logs minha-api --err pm2 install pm2-logrotate
Sem rotação, arquivos crescem até ocupar o disco. Configure tamanho, retenção e compressão; valide espaço com ferramentas do sistema. Não use pm2 flush como manutenção recorrente, pois ele apaga os arquivos atuais e pode eliminar evidência necessária para diagnóstico.
Produza logs estruturados com timestamp, nível, serviço, versão e ID de correlação. Nunca registre token, senha, cookie de sessão ou payload sensível.
Em ambientes importantes, envie logs a armazenamento externo; arquivos locais desaparecem com a máquina e não conectam eventos entre serviços.
Monitoramento e diagnóstico
pm2 monit e pm2 status ajudam na inspeção rápida de CPU, memória, uptime e reinícios. Para produção, acompanhe também latência, taxa de erro, saturação, fila, conexões, eventos do negócio e disponibilidade externa.
Um processo “online” pode responder lentamente ou falhar em todas as requisições.
Alertas devem detectar restart frequente, processo em estado errored, disco cheio, memória crescente e rota de saúde indisponível. Registre versão do commit ou build em cada deploy para correlacionar uma regressão. PM2 fornece sinais locais; métricas e traces completam a visão.

PM2 atrás de um proxy reverso
Mantenha a aplicação ouvindo em uma interface local e use Nginx ou outro proxy na borda. O proxy recebe portas 80 e 443, termina TLS, redireciona HTTP para HTTPS, aplica cabeçalhos, limites e encaminha o tráfego para a porta do Node.js.
O guia de proxy reverso com Nginx apresenta a configuração e os cuidados de segurança. Configure IPs confiáveis antes de aceitar cabeçalhos encaminhados; confiar em X-Forwarded-For de qualquer origem permite falsificação.
Deploy seguro com PM2
Evite editar código diretamente no diretório ativo. Um fluxo seguro prepara um release separado, instala dependências com lockfile, compila, testa e só então troca um link simbólico current ou outro apontamento atômico. Se falhar antes da troca, a versão ativa continua intacta.
- baixe o commit identificado em um novo diretório;
- instale dependências com comando reprodutível;
- compile e execute testes;
- aplique migrações compatíveis e com plano de reversão;
- troque o release ativo;
- recarregue pelo arquivo de ecossistema;
- verifique saúde, logs e fluxo real;
- se necessário, volte o link para o release anterior.
Rollback de código não desfaz automaticamente uma migração de dados. Prefira mudanças expansivas: adicione estrutura compatível, publique código que entenda os dois formatos, migre dados e remova a estrutura antiga em etapa posterior.
PM2 em pipelines de CI/CD
O pipeline deve produzir artefato rastreável, executar testes e chamar um script de deploy com permissões mínimas. Não permita que qualquer branch execute comandos no servidor. Proteja chaves SSH, restrinja host e usuário e mantenha a aprovação exigida pelo risco.
Depois da publicação, valide do lado de fora: HTTPS, status, versão, endpoint crítico e ausência de pico de erros. O artigo de CI/CD com testes e deploy seguro aprofunda gates, segredos e rollback.
Segurança operacional
- execute PM2 e a aplicação com usuário sem root;
- restrinja SSH e use chaves, firewall e atualizações do sistema;
- não exponha porta interna do Node.js quando existe proxy;
- mantenha segredos fora do código e com permissões mínimas;
- fixe dependências e audite atualizações;
- limite tamanho de requisições e taxa na aplicação ou borda;
- proteja logs e diretório
~/.pm2; - mantenha backup e teste restauração dos dados, não apenas do processo.
PM2 reinicia código comprometido tão bem quanto código legítimo; ele não é uma fronteira de segurança. A proteção depende de sistema, aplicação, credenciais, rede e processo de entrega.
PM2, systemd ou containers?
PM2 oferece experiência específica para aplicações, cluster, ecosystem e comandos amigáveis. systemd é nativo do Linux, controla serviços de modo geral e integra bem com journal, limites e dependências do sistema.
É possível usar systemd para iniciar o daemon PM2, que então administra as aplicações.
Em containers, o orquestrador costuma reiniciar e replicar processos, e o padrão simples é um processo principal por container. PM2 pode ser útil quando você precisa de seus recursos dentro do container, mas não deve duplicar políticas de reinício e escala sem entender quem é responsável.
O guia Docker descomplicado ajuda a separar isolamento de processo e gerenciamento da máquina.
Problemas comuns e como diagnosticar
- Processo não aparece: confira usuário,
PM2_HOMEe se o comando foi executado com sudo. - Reboot não restaura: valide serviço de startup, caminho do Node e
pm2 save. - Script não encontrado: revise
cwd, release ativo, build e permissões. - Variável antiga: confirme fonte, ambiente selecionado e reinício com configuração atual.
- Crash loop: leia o primeiro erro, não apenas o último; revise dependências e acesso a portas.
- Cluster duplica tarefas: jobs e cron estão rodando em todas as instâncias; separe worker ou faça eleição/lock.
- Reload cai para restart: prontidão ou shutdown não terminou dentro dos timeouts.
- Disco cheio: logs não foram rotacionados ou outra camada está crescendo.
Comece com pm2 show nome, pm2 logs nome --lines 200, estado do serviço, espaço em disco e uma requisição local à porta. Depois teste o proxy e a URL externa. Separar camadas evita culpar PM2 por DNS, TLS ou banco.
Fluxo completo de publicação
Um primeiro deploy confiável pode seguir esta ordem: preparar usuário e diretório; instalar Node e PM2; publicar release; validar variáveis; iniciar com ecosystem; testar localmente; configurar proxy e TLS; executar startup e save; reiniciar o servidor; confirmar restauração e monitoramento.
Nos deploys seguintes, gere release separado, teste, troque o apontamento, execute reload e valide externamente.
Registre versão, horário e responsável. Se houver regressão, reverta o release e investigue sem editar produção às pressas.
Checklist de PM2 em produção
- PM2 roda com usuário dedicado e sem root?
- Node.js, PM2 e dependências têm versões controladas?
- O arquivo ecosystem registra nome, cwd, script, modo e limites?
- Segredos ficam fora do repositório?
- Startup foi criado para o usuário correto e a lista foi salva?
- O reboot real foi testado?
- Modo cluster é compatível com estado, tarefas e WebSockets?
- Aplicação sinaliza prontidão e encerra conexões graciosamente?
- Logs possuem timestamps, rotação e proteção de dados?
- Memória, reinícios, latência e saúde externa geram alertas?
- A porta Node fica protegida atrás do proxy reverso?
- O deploy possui testes, verificação e rollback?
Perguntas frequentes
PM2 substitui o Nginx?
Não. PM2 gerencia processos; Nginx atua como proxy reverso, termina TLS e recebe tráfego HTTP na borda. Em uma VPS, eles normalmente trabalham juntos: Nginx encaminha para a porta local da aplicação administrada pelo PM2.
PM2 deve ser instalado globalmente?
Na administração direta de uma VPS, a instalação global é comum e facilita a CLI do usuário de deploy. Em projetos empacotados ou containers, uma dependência local pode tornar a versão reproduzível. Em ambos os casos, fixe a estratégia e saiba qual binário inicia o daemon.
Vale usar PM2 dentro de Docker?
Depende. Se a plataforma já reinicia, replica e observa containers, um processo por container costuma ser mais simples. PM2 faz sentido quando recursos como gerenciamento de múltiplos processos são uma exigência consciente. Evite duas camadas competindo por reinício e escala.
Devo usar watch em produção?
Normalmente não. Produção deve receber releases deliberados e imutáveis. Watch pode recarregar por alterações de logs, uploads ou arquivos temporários e esconder mudanças manuais. Use pipeline e comando explícito; se watch for indispensável, limite caminhos e exclusões com cuidado.
Conclusão
PM2 simplifica uma parte importante da operação de Node.js em uma VPS: mantém processos ativos, centraliza configuração, restaura serviços após reboot, oferece cluster e permite reload gradual.
Esses recursos só se tornam confiáveis quando usuário, ambiente, startup, logs, limites e sinais da aplicação estão bem definidos.
Comece em fork, valide a aplicação, transforme opções em um arquivo ecosystem e teste o reboot. Depois avance para cluster, prontidão, shutdown gracioso e deploy automatizado.
Assim, PM2 deixa de ser um comando que “faz o Node rodar” e passa a integrar uma operação previsível, observável e reversível.