Skip to content
GitHub

Runbook: Deploy de Aplicaciones

Propósito: Deploy de Orchestrator (backend) y Sevastopol (frontend) desde desarrollo a producción.

Frecuencia: Semanal/quincenal (según roadmap)

Tiempo estimado: 30-45 minutos

Criticidad: 🔴 ALTA - Requiere downtime planificado


Antes de iniciar deploy, verificar:

  • SSH access a servidor de producción
  • Git credentials configurados
  • Variables de entorno production en .env.production
  • Backup de base de datos completado (ver Runbook: Backup)
  • Tests passing en CI/CD (GitHub Actions green)
  • Downtime window aprobado por stakeholders

  1. Conectar a servidor de producción

    Terminal window
    cd /opt/nostromo
  2. Pull latest code

    Terminal window
    # Orchestrator
    cd /opt/nostromo/orchestrator && git pull origin main
    # Sevastopol
    cd /opt/nostromo/sevastopol && git pull origin main
  3. Install dependencies

    Terminal window
    cd /opt/nostromo/orchestrator && npm ci
    cd /opt/nostromo/sevastopol && npm ci
  4. Run database migrations

    Terminal window
    cd /opt/nostromo/orchestrator && npm run migrate:production
  5. Build production bundles

    Terminal window
    cd /opt/nostromo/orchestrator && npm run build
    cd /opt/nostromo/sevastopol && npm run build
  6. Stop services

    Terminal window
    pm2 stop orchestrator sevastopol
  7. Restart services

    Terminal window
    pm2 start orchestrator sevastopol && sleep 30
  8. Verify service status

    Terminal window
    pm2 status

Ejecutar health checks para confirmar deploy exitoso:

Terminal window
# Orchestrator health endpoint
curl http://localhost:8000/health
# Expected: {"status":"ok","version":"1.2.3"}
# Sevastopol (via Nginx proxy)
curl http://localhost:80/
# Expected: HTTP 200 OK
Terminal window
# Login (obtener JWT)
curl -X POST http://localhost:8000/api/command/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"***"}'
# Expected: {"token":"eyJhbGc..."}
Terminal window
# PM2 logs
pm2 logs orchestrator --lines 50
pm2 logs sevastopol --lines 50
# systemd logs
sudo journalctl -u orchestrator -n 50 --no-pager
sudo journalctl -u sevastopol -n 50 --no-pager

Buscar errores:

  • ERROR, FATAL, UnhandledPromiseRejection
  • Server listening on port 8000, Build complete

Ejecutar smoke tests mínimos:

  • Login en Sevastopol funciona
  • Dashboard carga datos
  • API /api/common/indicadores retorna UF/UTM
  • Query a tenant específico funciona (verificar multi-tenancy)

Si deploy falla o produce errores críticos:

  1. Revert Git commits

    Terminal window
    cd /opt/nostromo/orchestrator && git log --oneline -5
    git checkout <previous-commit-hash>
  2. Restore database backup

    Ver Runbook: Backup - sección “Restore Procedure”.

    Terminal window
    cd /opt/nostromo/backups && ls -lht | head -10
    psql -U postgres -d nostromo < backup_2026-01-18_pre-deploy.sql
  3. Rebuild with previous code

    Terminal window
    npm ci && npm run build
  4. Restart services

    Terminal window
    pm2 restart orchestrator sevastopol
  5. Verify rollback

    Terminal window
    curl http://localhost:8000/health

Documentar deploy en changelog interno:

## 2026-01-18 - Production Deploy v1.2.3
**Changes**:
- Feature: Added admin endpoints for capital management
- Fix: Corrected PPM calculation for regime B
- Chore: Updated dependencies
**Migration**: 002_add_admin_indexes.sql
**Downtime**: 3 minutes
**Rolled back**: No

Comunicar deploy exitoso:

  • Slack: #deployments channel
  • Email: stakeholders (si cambios mayores)

Monitorear métricas post-deploy por 24 horas:

  • Error rate (debe mantenerse baseline o bajar)
  • Response time (no debe aumentar significativamente)
  • User complaints (support tickets)

Síntoma: pm2 status muestra errored o stopped.

Debugging:

Terminal window
pm2 logs orchestrator --err --lines 100
# Buscar stack trace

Causas comunes:

  • Puerto ya en uso: Error: listen EADDRINUSE :::8000
    • Fix: Matar proceso anterior kill -9 $(lsof -t -i:8000)
  • Missing env vars: Error: JWT_SECRET is not defined
    • Fix: Verificar .env.production existe y está poblado
  • Database connection failed: Error: connect ECONNREFUSED
    • Fix: Verificar PostgreSQL running sudo systemctl status postgresql

Síntoma: npm run migrate:production exits with error.

Debugging:

Terminal window
cat logs/migration.log
# Ver error específico

Causas comunes:

  • Syntax error en SQL: ERROR: syntax error at or near "CRATE"
    • Fix: Corregir typo en migration file, commit, re-deploy
  • Migration already applied: ERROR: relation "users" already exists
    • Fix: Migration ya corrió (OK, continuar)
  • Foreign key constraint: ERROR: violates foreign key constraint
    • Fix: Verificar orden de migrations, puede necesitar seed data

Síntoma: Grafana/logs muestran spike de errores después de deploy.

Action:

  1. Identify error pattern: grep ERROR logs/orchestrator.log | head -20
  2. If critical (mayor a 10% error rate): Ejecutar rollback inmediatamente
  3. If non-critical (menor a 5% error rate): Investigar, puede ser issue menor

Estado actual: Deploy es manual siguiendo este runbook.

Mejoras planeadas:

  1. CI/CD Pipeline: GitHub Actions auto-deploy a staging on merge to develop
  2. Blue-Green Deploy: Deploy a instancia nueva, switch traffic sin downtime
  3. Automated health checks: Script que valida todo antes de finalizar deploy
  4. Rollback automático: Si health checks fallan, rollback automático

Timeline: Q2 2026



FechaVersionCambios
2026-01-181.0Runbook inicial creado