Voltar para blog

Do caos ao controle com Node.js, NVM e PM2: padrão operacional para produção mista

30/01/2026 · 1 min · Desenvolvimento

Compartilhar

Ambiente com legado Node 14 e serviço novo Node 20 tende a quebrar quando o host depende de binário global. O modelo que estabilizou minha operação foi isolar runtime por aplicação e padronizar gerenciamento de processo com PM2.

Problema de base

Sem isolamento:

  1. update global quebra app antigo;
  2. processo iniciado com node app.js & morre e não retorna;
  3. reboot do host derruba tudo sem auto-recuperação.

Etapa 1: runtime por projeto com NVM

nvm install 14
nvm install 20

Em cada projeto:

echo "14" > .nvmrc   # legado
# ou
echo "20" > .nvmrc   # novo serviço

Etapa 2: PM2 com interpreter explícito

Não confio em nvm use manual para produção. Defino binário no ecosystem.config.js.

module.exports = {
  apps: [
    {
      name: "legacy-app",
      script: "./server.js",
      interpreter: "/home/user/.nvm/versions/node/v14.21.3/bin/node",
      env: { NODE_ENV: "production" }
    },
    {
      name: "new-api",
      script: "./dist/main.js",
      interpreter: "/home/user/.nvm/versions/node/v20.10.0/bin/node",
      instances: "max",
      exec_mode: "cluster"
    }
  ]
}

Etapa 3: persistência pós-reboot

pm2 start ecosystem.config.js
pm2 save
pm2 startup

Monitoramento que aplico

  1. status e restart count:
pm2 status
pm2 monit
  1. logs por aplicação:
pm2 logs legacy-app --lines 100
pm2 logs new-api --lines 100
  1. alarme para loop de restart e memory leak.

Rollback de versão sem downtime longo

Se versão nova quebra app:

  1. alterar interpreter no ecosystem para versão anterior;
  2. pm2 reload da aplicação afetada;
  3. validar endpoint e logs.

Esse rollback é rápido porque a versão antiga já está instalada no NVM.

Conclusão

NVM resolve compatibilidade de runtime. PM2 resolve continuidade operacional. Juntos, entregam base estável para servidor com aplicações em ciclos de vida tecnológicos diferentes, sem depender de upgrade global arriscado.

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.