DeployCI/CDZero downtime5 min de lectura

Actualizar tu bot sin downtime

Estrategias de deploy con git pull + PM2 reload, blue-green con systemd y CI/CD con GitHub Actions.


¿Por qué zero downtime?

Cada vez que reiniciás tu bot, los usuarios ven que se desconecta brevemente. Con las técnicas correctas podés minimizar o eliminar ese tiempo muerto.

Método 1: PM2 Reload (graceful)

PM2 reload inicia una nueva instancia antes de matar la anterior:

bash
#!/bin/bash
# deploy.sh
cd /opt/bots/mi-bot
git pull origin main
npm install --production
pm2 reload mi-bot
echo "Deploy completado: $(date)"

Para que funcione correctamente, manejá el shutdown graceful:

javascript
process.on('SIGINT', async () => {
  console.log('Cerrando conexiones...');
  await client.destroy();
  process.exit(0);
});

Método 2: Blue-Green con systemd

Tené dos instancias y alterná entre ellas:

bash
# Estructura
/opt/bots/mi-bot-blue/   # Versión activa
/opt/bots/mi-bot-green/  # Versión nueva

Script de deploy:

bash
#!/bin/bash
ACTIVE=$(systemctl is-active discord-bot-blue && echo 'blue' || echo 'green')
NEW=$([ "$ACTIVE" = 'blue' ] && echo 'green' || echo 'blue')

cd /opt/bots/mi-bot-$NEW
git pull origin main
npm install --production

# Iniciar la nueva versión
sudo systemctl start discord-bot-$NEW
sleep 5

# Verificar que arrancó bien
if systemctl is-active --quiet discord-bot-$NEW; then
  sudo systemctl stop discord-bot-$ACTIVE
  echo "Switched to $NEW"
else
  sudo systemctl stop discord-bot-$NEW
  echo "Deploy fallido, $ACTIVE sigue activo"
  exit 1
fi

Método 3: CI/CD con GitHub Actions

Automatizá el deploy en cada push a main:

yaml
# .github/workflows/deploy.yml
name: Deploy Bot
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}
          username: deploy
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /opt/bots/mi-bot
            git pull origin main
            npm install --production
            pm2 reload mi-bot

Configurá los secrets en tu repositorio de GitHub:

  • VPS_HOST: IP de tu VPS en Baires Host
  • SSH_PRIVATE_KEY: Clave SSH privada del usuario deploy

Graceful shutdown en discord.js

javascript
const shutdown = async () => {
  console.log('Shutdown iniciado...');
  // Guardar estado pendiente en DB
  await saveState();
  // Desconectar el bot
  client.destroy();
  process.exit(0);
};

process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);

Recomendaciones

  • Usá pm2 reload en vez de pm2 restart para zero downtime
  • Implementá graceful shutdown para no perder datos
  • Testeá el deploy en un entorno de staging antes de producción
  • Configurá notificaciones de deploy exitoso/fallido en Discord

¿Te resultó útil esta guía?