PM2

Gerenciamento de processos com PM2, cluster mode e zero-downtime deploy.

O PlazerCLI gera um arquivo ecosystem.config.cjs para o PM2, pronto para rodar em producao com cluster mode e zero-downtime reload.

Arquivo de configuracao

// ecosystem.config.cjs
module.exports = {
  apps: [
    {
      name: 'api',
      script: 'apps/api/dist/main.js',
      instances: 'max',         // usa todos os cores
      exec_mode: 'cluster',     // cluster mode
      autorestart: true,
      watch: false,
      max_memory_restart: '1G',
      env: {
        NODE_ENV: 'production',
        PORT: 3001,
      },
      env_staging: {
        NODE_ENV: 'staging',
        PORT: 3001,
      },
      // Logs
      error_file: './logs/api-error.log',
      out_file: './logs/api-out.log',
      merge_logs: true,
      log_date_format: 'YYYY-MM-DD HH:mm:ss',
    },
  ],
};

Comandos essenciais

# Iniciar em producao
pm2 start ecosystem.config.cjs

# Zero-downtime reload (recarrega um worker por vez)
pm2 reload api

# Ver status
pm2 status

# Monitorar em tempo real
pm2 monit

# Ver logs
pm2 logs api --lines 100

# Salvar processo para auto-restart no reboot
pm2 save
pm2 startup

Deploy com PM2

O PlazerCLI configura um fluxo de deploy simples:

# Script de deploy (deploy.sh)
#!/bin/bash
set -e

echo "Pulling latest code..."
git pull origin main

echo "Installing dependencies..."
pnpm install --frozen-lockfile

echo "Building..."
pnpm run build

echo "Running migrations..."
cd apps/api && npx prisma migrate deploy && cd ../..

echo "Reloading PM2 (zero-downtime)..."
pm2 reload ecosystem.config.cjs

echo "Deploy complete!"

Health check com PM2

Configure o PM2 para verificar a saude da aplicacao apos reload:

// ecosystem.config.cjs (adicionar ao app)
{
  // ... demais configs
  listen_timeout: 10000,
  kill_timeout: 5000,
  wait_ready: true,          // espera o app sinalizar que esta pronto
  shutdown_with_message: true,
}

// No main.ts do app:
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
  // Sinalizar ao PM2 que o app esta pronto
  if (process.send) {
    process.send('ready');
  }
});

// Graceful shutdown
process.on('SIGINT', async () => {
  console.log('Graceful shutdown...');
  await app.close();       // fecha o servidor
  await prisma.$disconnect(); // fecha o banco
  process.exit(0);
});