workspace/projects/gamilit/docs/95-guias-desarrollo/GUIA-DESPLIEGUE-PRODUCCION-COMPLETA.md
rckrdmrd a23f31ce8f feat(db): Sincronizar scripts de BD y documentacion de produccion
## Scripts de Base de Datos (12 archivos)
- init-database.sh: Inicializacion completa con usuario y BD
- init-database-v3.sh: Version con dotenv-vault
- reset-database.sh: Reset BD manteniendo usuario
- recreate-database.sh: Recreacion completa
- cleanup-duplicados.sh, fix-duplicate-triggers.sh
- verify-users.sh, verify-missions-status.sh
- load-users-and-profiles.sh, DB-127-validar-gaps.sh

## Scripts de Produccion (5 archivos)
- build-production.sh: Compilar backend y frontend
- deploy-production.sh: Desplegar con PM2
- pre-deploy-check.sh: Validaciones pre-deploy
- repair-missing-data.sh: Reparar datos faltantes
- migrate-missing-objects.sh: Migrar objetos SQL

## Documentacion (7 archivos)
- GUIA-DESPLIEGUE-PRODUCCION-COMPLETA.md
- GUIA-ACTUALIZACION-PRODUCCION.md
- GUIA-VALIDACION-PRODUCCION.md
- GUIA-DEPLOYMENT-AGENTE-PRODUCCION.md
- GUIA-SSL-NGINX-PRODUCCION.md
- GUIA-SSL-AUTOFIRMADO.md
- DIRECTIVA-DEPLOYMENT.md

## Actualizaciones DDL/Seeds
- 99-post-ddl-permissions.sql: Permisos actualizados
- LOAD-SEEDS-gamification_system.sh: Seeds completos

## Nuevos archivos
- PROMPT-AGENTE-PRODUCCION.md: Prompt para agente productivo
- FLUJO-CARGA-LIMPIA.md: Documentacion de carga limpia

Resuelve: Problema de carga de BD entre dev y produccion
Cumple: DIRECTIVA-POLITICA-CARGA-LIMPIA.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 15:01:03 -06:00

38 KiB

Guia Completa de Despliegue en Produccion - GAMILIT

Version: 1.0.0 Fecha: 2025-12-18 Servidor: 74.208.126.102 Autor: Documentacion generada por analisis de configuracion existente


Indice

  1. Resumen Ejecutivo
  2. Arquitectura de Produccion
  3. Pre-requisitos del Servidor
  4. Configuracion de Base de Datos
  5. Configuracion de Aplicaciones
  6. Proceso de Despliegue con PM2
  7. Configuracion HTTPS con Certbot
  8. Comandos de Referencia Rapida
  9. Troubleshooting

1. Resumen Ejecutivo

Componentes Desplegados

Componente Puerto Instancias Tecnologia
Backend API 3006 2 (cluster) NestJS + TypeORM
Frontend 3005 1 (fork) React + Vite
PostgreSQL 5432 1 PostgreSQL 16+

URLs de Acceso

Frontend:    http://74.208.126.102:3005
Backend API: http://74.208.126.102:3006/api
API Docs:    http://74.208.126.102:3006/api/docs (deshabilitado en produccion)

2. Arquitectura de Produccion

                    ┌─────────────────────────────────────────────────────────────┐
                    │                  SERVIDOR 74.208.126.102                     │
                    │                                                              │
  Usuario           │   ┌──────────────┐      ┌──────────────────────────────┐    │
     │              │   │   Frontend   │      │         Backend API          │    │
     │              │   │  (Vite)      │      │        (NestJS)              │    │
     │              │   │  :3005       │      │        :3006                 │    │
     ▼              │   │              │      │  ┌────────┐  ┌────────┐     │    │
  ┌──────┐          │   │  1 instancia │      │  │ Inst 1 │  │ Inst 2 │     │    │
  │ HTTP │──────────┼───┤              │◄─────┼──┤ Cluster│  │ Cluster│     │    │
  └──────┘          │   └──────────────┘      │  └────────┘  └────────┘     │    │
                    │                         └──────────────┬───────────────┘    │
                    │                                        │                     │
                    │                                        ▼                     │
                    │                         ┌──────────────────────────────┐    │
                    │                         │      PostgreSQL 16+          │    │
                    │                         │         :5432                │    │
                    │                         │   DB: gamilit_platform       │    │
                    │                         └──────────────────────────────┘    │
                    │                                                              │
                    │   ┌──────────────────────────────────────────────────────┐  │
                    │   │                       PM2                             │  │
                    │   │  - Gestion de procesos                               │  │
                    │   │  - Auto-restart                                       │  │
                    │   │  - Cluster mode (backend)                            │  │
                    │   │  - Logs centralizados                                │  │
                    │   └──────────────────────────────────────────────────────┘  │
                    └─────────────────────────────────────────────────────────────┘

3. Pre-requisitos del Servidor

Software Requerido

Software Version Minima Comando de Verificacion
Node.js 18.0.0+ node -v
npm 9.0.0+ npm -v
PostgreSQL 16+ psql --version
PM2 Latest pm2 -v
Git Latest git --version

Instalacion de PM2 (si no esta instalado)

npm install -g pm2

Verificacion Pre-Deploy

# Verificar Node.js
node -v     # Debe ser >= 18.0.0

# Verificar npm
npm -v      # Debe ser >= 9.0.0

# Verificar PostgreSQL
psql --version

# Verificar PM2
pm2 -v

# Verificar espacio en disco
df -h

4. Configuracion de Base de Datos

4.1 Estructura de Schemas

La base de datos contiene 17 schemas:

Schema Descripcion
auth Autenticacion (Supabase-compatible)
auth_management Gestion de usuarios, perfiles, roles
educational_content Modulos, ejercicios, rubricas
gamification_system XP, ML Coins, logros, rangos, tienda
progress_tracking Progreso de usuarios, intentos
social_features Escuelas, aulas, amistades
notifications Sistema de notificaciones
content_management Gestion de contenido
communication Mensajeria entre usuarios
audit_logging Logs de auditoria
system_configuration Feature flags, parametros
admin_dashboard Vistas administrativas
lti_integration Learning Tools Interoperability
storage Almacenamiento de archivos
gamilit Funciones compartidas
public Schema legacy

4.2 Credenciales de Base de Datos

# Variables de entorno requeridas
DB_HOST=localhost
DB_PORT=5432
DB_NAME=gamilit_platform
DB_USER=gamilit_user
DB_PASSWORD=<CONTRASEÑA_SEGURA>

4.3 Crear Base de Datos desde Cero

Opcion A: Creacion Limpia (Recomendado para primer despliegue)

cd apps/database

# Definir URL de conexion
export DATABASE_URL="postgresql://gamilit_user:<PASSWORD>@localhost:5432/gamilit_platform"

# Ejecutar script de creacion
./create-database.sh "$DATABASE_URL"

Opcion B: Drop y Recreacion (Para reset completo)

cd apps/database

# ADVERTENCIA: Esto ELIMINARA toda la data existente
export DATABASE_URL="postgresql://gamilit_user:<PASSWORD>@localhost:5432/gamilit_platform"

./drop-and-recreate-database.sh "$DATABASE_URL"

4.4 Fases de Creacion de Base de Datos

El script create-database.sh ejecuta 16 fases en orden:

Fase Descripcion Contenido
0 Extensions pgcrypto, uuid-ossp
1 Prerequisites Schemas y ENUMs base
2 Funciones Compartidas Schema gamilit
3 Auth Schema Autenticacion Supabase
4 Storage Schema Almacenamiento
5 Auth Management Usuarios, perfiles
6 Educational Content Modulos, ejercicios
6.5 Notifications Sistema de notificaciones
7 Gamification System XP, rangos, logros
8 Progress Tracking Progreso usuarios
9 Social Features Escuelas, aulas
9.5 FK Constraints Dependencias circulares
10 Content Management Gestion contenido
10.5 Communication Mensajeria
11 Audit Logging Logs auditoria
12-15 Otros Config, Admin, LTI
16 Seeds PROD 57 archivos de datos iniciales

4.5 Seeds de Produccion (57 archivos)

Los seeds de produccion cargan:

Categoria Registros Descripcion
Usuarios 48 3 testing + 45 produccion
Modulos 5 Modulos educativos (M1-M5)
Ejercicios 23 M1: 5, M2: 5, M3: 5, M4: 5, M5: 3
Logros 30 Achievement system
Rangos Maya 5 Ajaw, Nacom, Ah K'in, Halach Uinic, K'uk'ulkan
Tienda 25 5 categorias, 20 items
Misiones 11 Templates de misiones
Feature Flags 26 Configuracion de features
Escuelas 2+ Demo + produccion
Aulas 4+ Aulas de prueba

5. Configuracion de Aplicaciones

5.1 Backend - .env.production

Ubicacion: apps/backend/.env.production

# ============================================================================
# GAMILIT Backend - Production Environment
# Servidor: 74.208.126.102
# ============================================================================

# Server
NODE_ENV=production
PORT=3006
API_PREFIX=api

# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=gamilit_platform
DB_USER=gamilit_user
DB_PASSWORD=${DB_PASSWORD}
DB_SYNCHRONIZE=false
DB_LOGGING=false

# JWT (IMPORTANTE: Cambiar a valor seguro)
# Generar con: openssl rand -base64 32
JWT_SECRET=${JWT_SECRET}
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d

# CORS
CORS_ORIGIN=http://74.208.126.102:3005,http://74.208.126.102,http://74.208.126.102:80
ENABLE_CORS=true
ENABLE_SWAGGER=false

# Logging
LOG_LEVEL=warn
LOG_TO_FILE=true

# Rate Limiting
RATE_LIMIT_TTL=60
RATE_LIMIT_MAX=100

# Session
SESSION_SECRET=${SESSION_SECRET}
SESSION_MAX_AGE=86400000

# Email
EMAIL_FROM=noreply@gamilit.com
EMAIL_REPLY_TO=support@gamilit.com

# Frontend URL
FRONTEND_URL=http://74.208.126.102:3005

5.2 Frontend - .env.production

Ubicacion: apps/frontend/.env.production

# ============================================================================
# GAMILIT Frontend - Production Environment
# Servidor: 74.208.126.102
# ============================================================================

# Application
VITE_APP_NAME=GAMILIT Platform
VITE_APP_VERSION=1.0.0
VITE_APP_ENV=production
VITE_ENV=production

# API Configuration
VITE_API_HOST=74.208.126.102:3006
VITE_API_PROTOCOL=http
VITE_API_VERSION=v1
VITE_API_TIMEOUT=30000

# WebSocket
VITE_WS_HOST=74.208.126.102:3006
VITE_WS_PROTOCOL=ws

# Authentication
VITE_JWT_EXPIRATION=7d

# Feature Flags
VITE_ENABLE_GAMIFICATION=true
VITE_ENABLE_SOCIAL_FEATURES=true
VITE_ENABLE_ANALYTICS=true
VITE_ENABLE_DEBUG=false
VITE_ENABLE_STORYBOOK=false
VITE_MOCK_API=false

# External Services (configurar en produccion)
VITE_GOOGLE_ANALYTICS_ID=
VITE_SENTRY_DSN=

# Logging
VITE_LOG_LEVEL=error

5.3 PM2 - ecosystem.config.js

Ubicacion: Raiz del proyecto

module.exports = {
  apps: [
    // BACKEND - NestJS API
    {
      name: 'gamilit-backend',
      cwd: './apps/backend',
      script: 'dist/main.js',
      node_args: '-r tsconfig-paths/register',
      instances: 2,           // 2 instancias en cluster
      exec_mode: 'cluster',
      autorestart: true,
      watch: false,
      max_memory_restart: '1G',
      env_production: {
        NODE_ENV: 'production',
        PORT: 3006,
      },
      env_file: './.env.production',
      error_file: '../../logs/backend-error.log',
      out_file: '../../logs/backend-out.log',
      log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
      merge_logs: true,
      min_uptime: '10s',
      max_restarts: 10,
      kill_timeout: 5000,
      wait_ready: true,
      listen_timeout: 10000,
    },

    // FRONTEND - Vite Preview
    {
      name: 'gamilit-frontend',
      cwd: './apps/frontend',
      script: 'npx',
      args: 'vite preview --port 3005 --host 0.0.0.0',
      instances: 1,
      exec_mode: 'fork',
      autorestart: true,
      watch: false,
      max_memory_restart: '512M',
      env_production: {
        NODE_ENV: 'production',
        VITE_ENV: 'production',
      },
      env_file: './.env.production',
      error_file: '../../logs/frontend-error.log',
      out_file: '../../logs/frontend-out.log',
      log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
      merge_logs: true,
      min_uptime: '10s',
      max_restarts: 10,
      kill_timeout: 5000,
    },
  ],
};

6. Proceso de Despliegue con PM2

6.1 Flujo Completo de Despliegue

┌─────────────────────────────────────────────────────────────────────────────┐
│                     PROCESO DE DESPLIEGUE PRODUCCION                         │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  PASO 1: Preparacion                                                         │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │ 1.1 git pull origin main                                               │ │
│  │ 1.2 Verificar pre-requisitos                                           │ │
│  │ 1.3 Configurar variables de entorno (.env.production)                  │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
│                              │                                               │
│                              ▼                                               │
│  PASO 2: Base de Datos (si es necesario)                                    │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │ 2.1 cd apps/database                                                   │ │
│  │ 2.2 export DATABASE_URL="postgresql://..."                             │ │
│  │ 2.3 ./create-database.sh "$DATABASE_URL"  (o drop-and-recreate)       │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
│                              │                                               │
│                              ▼                                               │
│  PASO 3: Build de Aplicaciones                                              │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │ 3.1 cd apps/backend && npm install && npm run build                    │ │
│  │ 3.2 cd apps/frontend && npm install && npm run build:prod              │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
│                              │                                               │
│                              ▼                                               │
│  PASO 4: Despliegue PM2                                                     │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │ 4.1 pm2 start ecosystem.config.js --env production                     │ │
│  │ 4.2 pm2 save                                                           │ │
│  │ 4.3 pm2 startup (para auto-inicio)                                     │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
│                              │                                               │
│                              ▼                                               │
│  PASO 5: Verificacion                                                        │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │ 5.1 pm2 status                                                         │ │
│  │ 5.2 curl http://74.208.126.102:3006/api/health                        │ │
│  │ 5.3 Acceder a http://74.208.126.102:3005                              │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

6.2 Comandos Paso a Paso

Paso 1: Preparacion

# Ir al directorio del proyecto
cd /path/to/gamilit

# Obtener ultimos cambios
git pull origin main

Paso 2: Base de Datos (Solo si es necesario)

# Ir al directorio de database
cd apps/database

# Configurar URL de conexion
export DATABASE_URL="postgresql://gamilit_user:TU_PASSWORD@localhost:5432/gamilit_platform"

# OPCION A: Crear base de datos nueva
./create-database.sh "$DATABASE_URL"

# OPCION B: Reset completo (ELIMINA TODA LA DATA)
./drop-and-recreate-database.sh "$DATABASE_URL"

# Volver al directorio raiz
cd ../..

Paso 3: Build de Aplicaciones

# Build Backend
cd apps/backend
npm install
npm run build

# Verificar build exitoso
ls -la dist/main.js

# Build Frontend
cd ../frontend
npm install
npm run build:prod

# Verificar build exitoso
ls -la dist/

# Volver al directorio raiz
cd ../..

Paso 4: Despliegue con PM2

# Crear directorio de logs
mkdir -p logs

# Detener procesos anteriores (si existen)
pm2 delete gamilit-backend gamilit-frontend 2>/dev/null || true

# Iniciar aplicaciones
pm2 start ecosystem.config.js --env production

# Guardar configuracion
pm2 save

# Configurar inicio automatico (primera vez)
pm2 startup
# Ejecutar el comando que muestre el output anterior

Paso 5: Verificacion

# Ver estado de procesos
pm2 status

# Verificar health del backend
curl http://74.208.126.102:3006/api/health

# Ver logs en tiempo real
pm2 logs

# Acceder al frontend en el navegador
# http://74.208.126.102:3005

6.3 Script Automatizado

Existe un script que automatiza el proceso:

# Ejecutar script de despliegue
./scripts/deploy-production.sh

Este script:

  1. Verifica que PM2 este instalado
  2. Verifica que los builds existan
  3. Verifica archivos .env.production
  4. Crea directorio de logs
  5. Detiene procesos PM2 existentes
  6. Inicia backend (2 instancias cluster)
  7. Inicia frontend (1 instancia)
  8. Guarda configuracion PM2
  9. Muestra resumen final

7. Configuracion HTTPS con Certbot

7.1 Arquitectura HTTPS

                           ARQUITECTURA HTTPS PRODUCCION
  ┌─────────────────────────────────────────────────────────────────────────────┐
  │                                                                              │
  │    Usuario                                                                   │
  │       │                                                                      │
  │       │ HTTPS (443)                                                          │
  │       ▼                                                                      │
  │   ┌────────────────────────────────────────────────────────────────────┐    │
  │   │                         NGINX REVERSE PROXY                         │    │
  │   │                         (Terminacion SSL)                           │    │
  │   │                                                                     │    │
  │   │  ┌─────────────────────┐    ┌─────────────────────────────────┐   │    │
  │   │  │ SSL Certificate     │    │ Rutas:                          │   │    │
  │   │  │ (Certbot/LE)        │    │   /       → Frontend :3005      │   │    │
  │   │  │                     │    │   /api    → Backend :3006       │   │    │
  │   │  │ /etc/letsencrypt/   │    │   /socket.io → Backend :3006    │   │    │
  │   │  └─────────────────────┘    └─────────────────────────────────┘   │    │
  │   └────────────────────────────────────────────────────────────────────┘    │
  │                         │                           │                        │
  │                         │ HTTP (interno)            │ HTTP (interno)         │
  │                         ▼                           ▼                        │
  │              ┌──────────────────┐        ┌──────────────────────┐           │
  │              │    Frontend      │        │      Backend         │           │
  │              │   (Vite)         │        │     (NestJS)         │           │
  │              │   :3005          │        │     :3006            │           │
  │              │   interno        │        │     interno          │           │
  │              └──────────────────┘        └──────────────────────┘           │
  │                                                                              │
  └─────────────────────────────────────────────────────────────────────────────┘

Concepto clave: Nginx actua como terminador SSL. Las aplicaciones (Backend/Frontend) siguen corriendo en HTTP internamente, pero todo el trafico externo usa HTTPS.

7.2 Requisitos para HTTPS

Requisito Descripcion Estado
Dominio Necesario para Certbot/Let's Encrypt Opcional (IP requiere certificado autofirmado)
Nginx Reverse proxy y terminador SSL Requerido
Certbot Cliente ACME para Let's Encrypt Requerido (con dominio)
Puertos abiertos 80 (HTTP), 443 (HTTPS) Requerido

7.3 Instalacion de Nginx y Certbot

# Actualizar repositorios
sudo apt update

# Instalar Nginx
sudo apt install nginx -y

# Verificar Nginx
sudo systemctl status nginx

# Instalar Certbot con plugin Nginx
sudo apt install certbot python3-certbot-nginx -y

# Verificar Certbot
certbot --version

7.4 Opcion A: HTTPS con Dominio (Recomendado)

Paso 1: Configurar DNS

Asegurar que el dominio apunte a la IP del servidor:

A Record:     gamilit.com      → 74.208.126.102
A Record:     www.gamilit.com  → 74.208.126.102
A Record:     api.gamilit.com  → 74.208.126.102 (opcional)

Paso 2: Configurar Nginx inicial (HTTP)

Crear /etc/nginx/sites-available/gamilit:

server {
    listen 80;
    server_name gamilit.com www.gamilit.com;

    # Frontend - React App
    location / {
        proxy_pass http://127.0.0.1:3005;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }

    # Backend API
    location /api {
        proxy_pass http://127.0.0.1:3006;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;

        # Timeouts para API
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # WebSocket
    location /socket.io {
        proxy_pass http://127.0.0.1:3006;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # Timeouts para WebSocket
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
    }
}

Habilitar sitio:

# Crear symlink
sudo ln -s /etc/nginx/sites-available/gamilit /etc/nginx/sites-enabled/

# Eliminar default si existe
sudo rm /etc/nginx/sites-enabled/default 2>/dev/null || true

# Verificar configuracion
sudo nginx -t

# Recargar Nginx
sudo systemctl reload nginx

Paso 3: Obtener Certificado SSL con Certbot

# Obtener certificado (automatico)
sudo certbot --nginx -d gamilit.com -d www.gamilit.com

# Durante el proceso:
# 1. Ingresar email para notificaciones
# 2. Aceptar terminos de servicio
# 3. Elegir si redirigir HTTP a HTTPS (recomendado: SI)

Certbot automaticamente:

  • Obtiene el certificado de Let's Encrypt
  • Modifica la configuracion de Nginx
  • Configura renovacion automatica

Paso 4: Verificar Configuracion Nginx (Post-Certbot)

Despues de ejecutar certbot, el archivo se vera asi:

server {
    listen 80;
    server_name gamilit.com www.gamilit.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name gamilit.com www.gamilit.com;

    # Certificados generados por Certbot
    ssl_certificate /etc/letsencrypt/live/gamilit.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/gamilit.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # Frontend - React App
    location / {
        proxy_pass http://127.0.0.1:3005;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Backend API
    location /api {
        proxy_pass http://127.0.0.1:3006;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # WebSocket (wss://)
    location /socket.io {
        proxy_pass http://127.0.0.1:3006;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
}

7.5 Opcion B: HTTPS con IP (Sin Dominio)

Si no tienes dominio, necesitas certificado autofirmado:

# Crear directorio para certificados
sudo mkdir -p /etc/nginx/ssl

# Generar certificado autofirmado (valido 365 dias)
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/gamilit.key \
  -out /etc/nginx/ssl/gamilit.crt \
  -subj "/C=MX/ST=Estado/L=Ciudad/O=Gamilit/CN=74.208.126.102"

Configuracion Nginx para IP con SSL:

server {
    listen 80;
    server_name 74.208.126.102;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name 74.208.126.102;

    # Certificado autofirmado
    ssl_certificate /etc/nginx/ssl/gamilit.crt;
    ssl_certificate_key /etc/nginx/ssl/gamilit.key;

    # Configuracion SSL
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_session_cache shared:SSL:10m;

    # Frontend
    location / {
        proxy_pass http://127.0.0.1:3005;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Backend API
    location /api {
        proxy_pass http://127.0.0.1:3006;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # WebSocket
    location /socket.io {
        proxy_pass http://127.0.0.1:3006;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
}

Nota: Los navegadores mostraran advertencia de certificado no confiable.

7.6 Actualizar Variables de Entorno para HTTPS

Backend .env.production

# ANTES (HTTP)
CORS_ORIGIN=http://74.208.126.102:3005,http://74.208.126.102
FRONTEND_URL=http://74.208.126.102:3005

# DESPUES (HTTPS con dominio)
CORS_ORIGIN=https://gamilit.com,https://www.gamilit.com,https://74.208.126.102
FRONTEND_URL=https://gamilit.com

# DESPUES (HTTPS con IP)
CORS_ORIGIN=https://74.208.126.102
FRONTEND_URL=https://74.208.126.102

Frontend .env.production

# ANTES (HTTP)
VITE_API_HOST=74.208.126.102:3006
VITE_API_PROTOCOL=http
VITE_WS_HOST=74.208.126.102:3006
VITE_WS_PROTOCOL=ws

# DESPUES (HTTPS con Nginx proxy - RECOMENDADO)
# Nginx maneja SSL, frontend accede via proxy
VITE_API_HOST=gamilit.com
VITE_API_PROTOCOL=https
VITE_WS_HOST=gamilit.com
VITE_WS_PROTOCOL=wss

# DESPUES (HTTPS con IP)
VITE_API_HOST=74.208.126.102
VITE_API_PROTOCOL=https
VITE_WS_HOST=74.208.126.102
VITE_WS_PROTOCOL=wss

7.7 Rebuild y Reinicio

Despues de cambiar las variables de entorno:

# 1. Rebuild del Frontend (variables VITE_ se embeben en build)
cd apps/frontend
npm run build:prod

# 2. Reiniciar servicios
pm2 restart all

# 3. Verificar Nginx
sudo nginx -t
sudo systemctl reload nginx

7.8 Renovacion Automatica de Certificados

Certbot configura renovacion automatica. Verificar:

# Ver timer de renovacion
sudo systemctl status certbot.timer

# Probar renovacion (dry-run)
sudo certbot renew --dry-run

# Forzar renovacion si es necesario
sudo certbot renew --force-renewal

Los certificados de Let's Encrypt expiran cada 90 dias. Certbot los renueva automaticamente.

7.9 URLs Finales con HTTPS

Con Dominio

Frontend:     https://gamilit.com
Backend API:  https://gamilit.com/api
WebSocket:    wss://gamilit.com/socket.io
Health Check: https://gamilit.com/api/health

Con IP (certificado autofirmado)

Frontend:     https://74.208.126.102
Backend API:  https://74.208.126.102/api
WebSocket:    wss://74.208.126.102/socket.io
Health Check: https://74.208.126.102/api/health

7.10 Verificacion HTTPS

# Verificar certificado SSL
curl -vI https://gamilit.com 2>&1 | grep -E "SSL|certificate|subject"

# Verificar API sobre HTTPS
curl -s https://gamilit.com/api/health | jq

# Verificar que HTTP redirige a HTTPS
curl -I http://gamilit.com

# Verificar WebSocket (requiere wscat)
npm install -g wscat
wscat -c wss://gamilit.com/socket.io

7.11 Checklist HTTPS

  • Nginx instalado y corriendo
  • Certbot instalado
  • Dominio configurado en DNS (o usar IP)
  • Configuracion Nginx creada en sites-available
  • Symlink creado en sites-enabled
  • nginx -t sin errores
  • Certificado SSL obtenido (certbot o autofirmado)
  • CORS_ORIGIN actualizado con https://
  • FRONTEND_URL actualizado con https://
  • VITE_API_PROTOCOL=https en frontend
  • VITE_WS_PROTOCOL=wss en frontend
  • Frontend recompilado (npm run build:prod)
  • PM2 reiniciado (pm2 restart all)
  • Nginx recargado (sudo systemctl reload nginx)
  • Health check responde sobre HTTPS
  • Frontend carga sin errores de mixed content
  • WebSocket conecta sobre wss://

8. Comandos de Referencia Rapida

PM2 - Operaciones Basicas

# Ver estado
pm2 status
pm2 list

# Logs
pm2 logs                      # Todos los logs
pm2 logs gamilit-backend      # Solo backend
pm2 logs gamilit-frontend     # Solo frontend

# Monitoreo
pm2 monit                     # Monitor interactivo

# Reinicio
pm2 restart all               # Reiniciar todo
pm2 restart gamilit-backend   # Solo backend
pm2 reload gamilit-backend    # Zero-downtime reload

# Detener
pm2 stop all
pm2 stop gamilit-backend

# Eliminar
pm2 delete all
pm2 delete gamilit-backend

PM2 - Operaciones Avanzadas

# Informacion detallada
pm2 show gamilit-backend

# Flush logs
pm2 flush

# Guardar configuracion
pm2 save

# Restaurar procesos guardados
pm2 resurrect

# Configurar inicio automatico
pm2 startup

# Actualizar PM2
pm2 update

Base de Datos

# Variables
export DATABASE_URL="postgresql://gamilit_user:PASSWORD@localhost:5432/gamilit_platform"

# Crear estructura DDL + Seeds
./create-database.sh "$DATABASE_URL"

# Drop y recrear (RESET TOTAL)
./drop-and-recreate-database.sh "$DATABASE_URL"

# Conectar a PostgreSQL
psql "$DATABASE_URL"

# Backup
pg_dump -U gamilit_user -d gamilit_platform -F c -f backup_$(date +%Y%m%d).dump

# Restore
pg_restore -U gamilit_user -d gamilit_platform -c backup_20251218.dump

Build

# Backend
cd apps/backend && npm run build

# Frontend (produccion)
cd apps/frontend && npm run build:prod

# Frontend (desarrollo)
cd apps/frontend && npm run build

9. Troubleshooting

Problema: Backend no inicia

# Ver logs de error
pm2 logs gamilit-backend --err --lines 50

# Verificar que el build existe
ls -la apps/backend/dist/main.js

# Verificar conexion a base de datos
psql "$DATABASE_URL" -c "SELECT 1"

# Verificar puerto no ocupado
sudo lsof -i :3006

Problema: Frontend no inicia

# Ver logs de error
pm2 logs gamilit-frontend --err --lines 50

# Verificar que el build existe
ls -la apps/frontend/dist/

# Verificar puerto no ocupado
sudo lsof -i :3005

Problema: Error de conexion a BD

# Verificar PostgreSQL corriendo
sudo systemctl status postgresql

# Reiniciar PostgreSQL
sudo systemctl restart postgresql

# Verificar usuario y permisos
psql -U postgres -c "\\du"
psql -U postgres -c "\\l"

Problema: Puerto ocupado

# Encontrar proceso usando el puerto
sudo lsof -i :3006
sudo lsof -i :3005

# Matar proceso
sudo kill -9 <PID>

# O usar fuser
sudo fuser -k 3006/tcp

Problema: Memoria alta

# Ver uso de memoria PM2
pm2 monit

# Reiniciar con limite de memoria
pm2 restart gamilit-backend --max-memory-restart 500M

Problema: CORS

# Verificar CORS_ORIGIN en backend
grep CORS_ORIGIN apps/backend/.env.production

# Debe incluir el origen del frontend
# CORS_ORIGIN=http://74.208.126.102:3005,http://74.208.126.102

Checklist de Despliegue

Pre-Despliegue

  • Verificar version de Node.js >= 18
  • Verificar version de npm >= 9
  • Verificar PostgreSQL corriendo
  • Verificar PM2 instalado
  • Actualizar codigo: git pull origin main

Base de Datos

  • Configurar DATABASE_URL
  • Ejecutar create-database.sh (o drop-and-recreate)
  • Verificar que los seeds cargaron correctamente

Configuracion

  • Configurar apps/backend/.env.production
  • Configurar apps/frontend/.env.production
  • Verificar JWT_SECRET es seguro
  • Verificar CORS_ORIGIN correcto

Build

  • Build backend: npm run build
  • Build frontend: npm run build:prod
  • Verificar archivos en dist/

Despliegue

  • Ejecutar pm2 start ecosystem.config.js --env production
  • Verificar pm2 status - ambos online
  • Ejecutar pm2 save
  • Configurar pm2 startup (primera vez)

Verificacion

  • Verificar health: curl http://74.208.126.102:3006/api/health
  • Acceder a frontend: http://74.208.126.102:3005
  • Probar login con usuario de prueba
  • Verificar logs sin errores: pm2 logs

Contacto y Soporte

Para problemas de despliegue:

  1. Revisar logs: pm2 logs
  2. Consultar esta documentacion
  3. Verificar docs/DEPLOYMENT.md para mas detalles
  4. Revisar docs/95-guias-desarrollo/DEPLOYMENT-GUIDE.md para HTTPS

Nota: Esta documentacion fue generada automaticamente analizando los archivos de configuracion existentes en el proyecto. Mantener actualizada cuando haya cambios en la arquitectura.