Files
openccb/ManualDeConfiguracion.md

20 KiB

Manual de Configuración de OpenCCB

Tabla de Contenidos

  1. Requisitos del Sistema
  2. Instalación
  3. Configuración de Entorno
  4. Configuración de IA
  5. Base de Datos
  6. Despliegue en Producción
  7. Solución de Problemas

Requisitos del Sistema

OpenCCB es altamente escalable. A continuación se detallan los requisitos recomendados según la carga de usuarios concurrentes:

Componente Pequeño (100 u.) Mediano (500 u. concurrentes) Grande (1000+ u.)
CPU 4 vCPUs 8-12 vCPUs (AVX2/AVX-512) 16-32+ vCPUs
RAM 8 GB 16-32 GB (Recomendado 24GB+) 64 GB+
Almacenamiento 50 GB SSD 250 GB+ NVMe (RAID-1) 1 TB+ NVMe (S3 Backup)
AI (Opcional) N/A (Solo CPU) NVIDIA RTX 3060+ (12GB VRAM) Multi-GPU (A100/H100)
OS Ubuntu 22.04 LTS Ubuntu 24.04 LTS / Debian Cloud Native (K8s / Terraform)

Note

Los requisitos de AI son específicos para la función de transcripción local (Whisper). Si se utiliza una API externa, el requisito de GPU desaparece.


Instalación

Instalación Automática (Recomendado)

El script install.sh automatiza todo el proceso:

# Instalación estándar
./install.sh

# Modo rápido (omite comprobaciones de dependencias)
./install.sh --fast

# Modo despliegue (sincroniza con servidor remoto)
./install.sh --deploy

Pasos del Script

  1. Entorno local forzado: ENVIRONMENT=dev
  2. Instalación de dependencias: Rust, Node.js, Docker, sqlx-cli
  3. Configuración de .env: Variables automáticas según entorno
  4. Inicialización de DB: Crea bases de datos y ejecuta migraciones
  5. Configuración de IA: URLs de Ollama y Whisper
  6. Creación de admin: Usuario administrador inicial
  7. Inicio de servicios: Docker Compose

Overrides útiles para install.sh

install.sh permite sobreescribir variables sin editar el script:

# IA local por IP/host de red
LOCAL_OLLAMA_URL=http://192.168.0.5:11434 \
LOCAL_WHISPER_URL=http://192.168.0.5:9000 \
./install.sh

# Forzar URL interna de CMS para comunicación LMS -> CMS
CMS_API_URL=http://studio:3001 ./install.sh

# Reutilizar SAM remoto compartido
SAM_SHARED_URL=mysql://user:pass@host:3306/sige_sam_v3 \
SAM_DIAG_SHARED_URL=mysql://user:pass@host:3306/SAM_diagnostico \
./install.sh

Instalación Manual

# 1. Clonar repositorio
git clone <repo-url>
cd openccb

# 2. Copiar .env.example
cp .env.example .env

# 3. Configurar variables de entorno
nano .env

# 4. Si PostgreSQL NO está corriendo, iniciar con Docker
docker-compose up -d db

# 5. Esperar a que DB esté lista
sleep 10

# 6. Crear bases de datos (puerto 5433)
docker exec openccb-db-1 psql -U user -d postgres -c "CREATE DATABASE openccb_cms;" || true
docker exec openccb-db-1 psql -U user -d postgres -c "CREATE DATABASE openccb_lms;" || true

# Si PostgreSQL ya existe (producción), usar psql directo:
# psql -h localhost -p 5433 -U user -d postgres -c "CREATE DATABASE openccb_cms;"
# psql -h localhost -p 5433 -U user -d postgres -c "CREATE DATABASE openccb_lms;"

# 7. Ejecutar migraciones (puerto 5433)
DATABASE_URL=postgresql://user:password@localhost:5433/openccb_cms \
  sqlx migrate run --source services/cms-service/migrations

DATABASE_URL=postgresql://user:password@localhost:5433/openccb_lms \
  sqlx migrate run --source services/lms-service/migrations

# 8. Iniciar servicios (sin DB si ya existe)
docker-compose up -d

Configuración de Entorno

Variables Principales (.env)

# Entorno (dev o prod)
ENVIRONMENT=dev

# Base de Datos (Puerto 5434 - 5432 y 5433 pueden estar en uso)
DATABASE_URL=postgresql://user:password@localhost:5434/openccb?sslmode=disable
CMS_DATABASE_URL=postgresql://user:password@localhost:5434/openccb_cms?sslmode=disable
LMS_DATABASE_URL=postgresql://user:password@localhost:5434/openccb_lms?sslmode=disable

# JWT Secret (generar con ./generate_jwt_secret.sh)
JWT_SECRET=tu_secreto_seguro_aqui

# URLs de Frontend
NEXT_PUBLIC_CMS_API_URL=http://localhost:3001
NEXT_PUBLIC_LMS_API_URL=http://localhost:3002

# Branding
DEFAULT_ORG_NAME=Norteamericano
DEFAULT_PLATFORM_NAME=OpenCCB Learning
DEFAULT_PRIMARY_COLOR=#3B82F6
DEFAULT_SECONDARY_COLOR=#8B5CF6

# SAM Integration (MySQL compartido)
MYSQL_DATABASE_URL=mysql://user:password@host:3306/sige_sam_v3
SAM_DATABASE_URL=mysql://user:password@host:3306/sige_sam_v3
SAM_DIAGNOSTICO_DATABASE_URL=mysql://user:password@host:3306/SAM_diagnostico
# URL interna para sincronización de perfil LMS -> CMS
CMS_API_URL=http://studio:3001

Configuración por Entorno

Desarrollo:

ENVIRONMENT=dev
LOCAL_OLLAMA_URL=http://localhost:11434
LOCAL_WHISPER_URL=http://localhost:9000
# Alternativa LAN:
# LOCAL_OLLAMA_URL=http://192.168.0.5:11434
# LOCAL_WHISPER_URL=http://192.168.0.5:9000

Producción:

ENVIRONMENT=prod
LOCAL_OLLAMA_URL=http://t-800.norteamericano.cl:11434
LOCAL_WHISPER_URL=http://t-800.norteamericano.cl:9000

Integración SAM (Sistema de Administración Académica)

¿Qué es SAM?

SAM es un sistema externo de gestión académica que contiene:

  • Alumnos: sige_sam_v3.alumnos
  • Cursos: sige_sam_v3.detalle_contrato

OpenCCB se sincroniza con SAM para:

  1. Importar alumnos automáticamente
  2. Asignar cursos a cada alumno
  3. Restringir acceso solo a cursos asignados

Configuración

  1. Agregar variables de entorno en .env:

MYSQL_DATABASE_URL=mysql://user:password@host:3306/sige_sam_v3 SAM_DATABASE_URL=mysql://user:password@host:3306/sige_sam_v3 SAM_DIAGNOSTICO_DATABASE_URL=mysql://user:password@host:3306/SAM_diagnostico


2. **Ejecutar migración**:
```bash
DATABASE_URL=postgresql://user:password@localhost:5433/openccb_cms \
  sqlx migrate run --source services/cms-service/migrations
  1. Sincronizar datos:
    # Obtener token de admin
    TOKEN=$(curl -s -X POST "http://localhost:3001/auth/login" \
      -H "Content-Type: application/json" \
      -d '{"email":"admin@norteamericano.cl","password":"Admin123!"}' \
      | jq -r '.token')
    
    # Sincronizar alumnos y cursos
    curl -X POST "http://localhost:3001/sam/sync-all" \
      -H "Authorization: Bearer $TOKEN"
    

Endpoints SAM

Método Endpoint Descripción
POST /sam/sync-all Sincronización completa (alumnos + cursos)
POST /sam/sync-students Solo sincroniza alumnos
POST /sam/sync-assignments Solo sincroniza asignaciones de cursos
GET /sam/students Lista alumnos SAM con filtros
GET /sam/students/{student_id}/courses Cursos asignados a un alumno

Comportamiento por Rol

Rol Acceso a Cursos
Super Admin Todos los cursos (todas las organizaciones)
Admin Todos los cursos de su organización
Instructor Todos los cursos de su organización
Alumno SAM Solo cursos asignados vía SAM
Alumno NO-SAM Ningún curso (lista vacía)

Flujo de Sincronización

┌─────────────────────┐     ┌──────────────┐     ┌─────────────────┐
│ sige_sam_v3.alumnos │────▶│  Sync SAM    │────▶│ users           │
│ (id_alumno, email)  │     │  POST /sam   │     │ (sam_student_id)│
└─────────────────────┘     └──────────────┘     └─────────────────┘

┌──────────────────────────┐     ┌──────────────┐     ┌──────────────┐
│ sige_sam_v3.detalle_     │────▶│  Sync SAM    │────▶│ sam_course_  │
│ contrato (id_alumno,     │     │  POST /sam   │     │ assignments  │
│ id_curso_abierto)        │     │              │     │              │
└──────────────────────────┘     └──────────────┘     └──────────────┘

Solución de Problemas

Error: "SAM_DATABASE_URL not configured"

# Agregar en .env
SAM_DATABASE_URL=mysql://user:pass@host:3306/sige_sam_v3

# Reiniciar servicio
docker-compose restart cms

Error: /auth/me responde 502 en LMS

# Validar URL interna de CMS usada por LMS
grep '^CMS_API_URL=' .env.dev .env 2>/dev/null

# Valor recomendado en Docker
CMS_API_URL=http://studio:3001

Error: "Failed to fetch SAM students"

  • Verificar conexión a la base de datos SAM
  • Confirmar que las tablas sige_sam_v3.alumnos existen
  • Verificar permisos de usuario en SAM

Alumnos SAM no ven cursos

  1. Verificar que is_sam_student = TRUE en tabla users
  2. Verificar que existen registros en sam_course_assignments
  3. Ejecutar sincronización nuevamente: POST /sam/sync-all

Configuración de IA

Proveedores Soportados

  1. Local (Ollama + Whisper): Recomendado para privacidad y costo cero
  2. Remoto: API externa (t-800 o similar)

Configuración Local

AI_PROVIDER=local
LOCAL_OLLAMA_URL=http://localhost:11434
LOCAL_WHISPER_URL=http://localhost:9000
LOCAL_LLM_MODEL=llama3.2:3b
EMBEDDING_MODEL=nomic-embed-text

Pull de Modelos

# Ollama
docker exec -it ollama ollama pull llama3.2:3b
docker exec -it ollama ollama pull nomic-embed-text

# Whisper (ya viene pre-configurado en el contenedor)

Generación de Embeddings

# Generar para preguntas existentes
curl -X POST http://localhost:3001/question-bank/embeddings/generate \
  -H "Authorization: Bearer TOKEN"

# Generar para base de conocimiento
curl -X POST http://localhost:3002/knowledge-base/embeddings/generate \
  -H "Authorization: Bearer TOKEN"

Base de Datos

Estructura

  • openccb_cms: Gestión de cursos, usuarios, organizaciones
  • openccb_lms: Progreso estudiantil, calificaciones, foros

Migraciones

# CMS
DATABASE_URL=postgresql://user:password@localhost:5433/openccb_cms \
  sqlx migrate run --source services/cms-service/migrations

# LMS
DATABASE_URL=postgresql://user:password@localhost:5433/openccb_lms \
  sqlx migrate run --source services/lms-service/migrations

# Revertir última migración
DATABASE_URL=postgresql://user:password@localhost:5433/openccb_cms \
  sqlx migrate revert --source services/cms-service/migrations

Backup

# Backup completo
docker exec openccb-db-1 pg_dump -U user openccb_cms > backup_cms.sql
docker exec openccb-db-1 pg_dump -U user openccb_lms > backup_lms.sql

# Restaurar
docker exec -i openccb-db-1 psql -U user openccb_cms < backup_cms.sql
docker exec -i openccb-db-1 psql -U user openccb_lms < backup_lms.sql

PGVector (Búsqueda Semántica)

La extensión pgvector está habilitada para búsqueda semántica:

-- Verificar extensión
SELECT * FROM pg_extension WHERE extname = 'vector';

-- Búsqueda semántica de preguntas
SELECT * FROM question_bank
ORDER BY embedding <=> '[...]'::vector
LIMIT 10;

Despliegue en Producción

Scripts de Despliegue

El proyecto cuenta con tres scripts separados:

Script Propósito
install.sh Instalación local y configuración inicial
deploy.sh Despliegue remoto automático
setup-nginx-ssl.sh Configuración de nginx + SSL (servidor con nginx instalado)

SSL con nginx Existente (Tu Caso)

Si nginx ya está instalado en el servidor remoto:

1. Copiar archivos al servidor:

# Desde tu máquina local
./deploy.sh

2. Conectarse al servidor:

ssh -i "ubuntu.pem" ubuntu@ec2-18-222-198-24.us-east-2.compute.amazonaws.com
cd /var/www/openccb

3. Ejecutar configuración de nginx:

sudo ./setup-nginx-ssl.sh

4. Instalar certificados SSL:

sudo /usr/local/bin/install-ssl-certs.sh

5. Iniciar OpenCCB:

docker-compose up -d

Configuración creada:

  • /etc/nginx/sites-available/studio.norteamericano.com
  • /etc/nginx/sites-available/learning.norteamericano.com
  • /usr/local/bin/install-ssl-certs.sh (instalación de certificados)
  • /etc/cron.daily/certbot-renewal (renovación automática)

Dominios configurados:

  • https://studio.norteamericano.com → Puerto 3000 (Studio)
  • https://learning.norteamericano.com → Puerto 3003 (Experience)

Despliegue con Docker Compose SSL

Si prefieres usar docker-compose con nginx-proxy:

# Ejecutar despliegue con SSL
docker compose -f docker-compose.ssl.yml up -d

¿Qué hace?

  1. Inicia nginx-proxy → Proxy inverso
  2. Inicia acme-companion → SSL automático con Let's Encrypt
  3. Inicia servicios → Studio, Experience, DB
  4. Obtiene certificados → Automáticamente

Comandos de Despliegue

# Despliegue remoto (copia archivos)
./deploy.sh

# Configuración de nginx + SSL (en el servidor)
sudo ./setup-nginx-ssl.sh

# Instalación de certificados (en el servidor)
sudo /usr/local/bin/install-ssl-certs.sh

# Instalación local (desarrollo)
./install.sh

Flujo de Despliegue

┌─────────────────┐
│  deploy.sh      │  (local)
│                 │
│  1. Lee config  │───┐
│  2. Prepara     │   │
│  3. Sube        │   ▼
└─────────────────┐ ┌──────────────────┐
                  │ │ Servidor Remoto  │
                  │ │                  │
                  │ │ 4. Verifica      │
                  │ │ 5. Gestiona      │
                  │ │ 6. Verifica      │
                  │ └──────────────────┘

Archivos Subidos al Servidor

El deploy.sh copia los siguientes archivos al servidor remoto:

/var/www/openccb/
├── docker-compose.yml
├── .env (o .env.example)
├── install.sh          ← Para instalaciones futuras
├── deploy.sh           ← Para actualizaciones futuras
├── Cargo.toml
├── Cargo.lock
├── services/
├── shared/
└── web/

Actualizaciones Futuras

Una vez desplegado, puedes actualizar el servidor remoto de dos formas:

Opción A: Desde tu máquina local

./deploy.sh

Opción B: Desde el servidor remoto

ssh -i ubuntu.pem ubuntu@REMOTE_HOST
cd /var/www/openccb
./deploy.sh

Pasos Manuales (Alternativo)

Si prefieres control manual del despliegue:

  1. Sincronizar archivos:

    rsync -avz -e "ssh -i ubuntu.pem" \
      --exclude 'node_modules' \
      --exclude 'target' \
      --exclude '.next' \
      --exclude '.git' \
      --exclude '*.md' \
      ./ ubuntu@remote-host:/var/www/openccb/
    
  2. Conectarse al servidor:

    ssh -i ubuntu.pem ubuntu@remote-host
    cd /var/www/openccb
    
  3. Gestionar contenedores:

    # Ver estado
    docker-compose ps
    
    # Ver logs
    docker-compose logs -f
    
    # Reiniciar servicios
    docker-compose restart
    
    # Reconstruir desde cero
    docker-compose down
    docker-compose up -d --build
    
    # Actualizar desde git
    git pull
    docker-compose up -d --build
    

Configuración de Producción

# .env en producción
ENVIRONMENT=prod
JWT_SECRET=<generar_con_script>
DATABASE_URL=postgresql://user:secure_password@db-host:5432/openccb?sslmode=require
LOCAL_OLLAMA_URL=http://t-800.norteamericano.cl:11434
LOCAL_WHISPER_URL=http://t-800.norteamericano.cl:9000

Seguridad en Producción

  1. HTTPS obligatorio: Usar reverse proxy (Nginx/Traefik) con Let's Encrypt
  2. Firewall: Solo puertos 80, 443, 22 abiertos
  3. DB password: Usar contraseña segura (20+ caracteres)
  4. JWT_SECRET: Generar con ./generate_jwt_secret.sh
  5. Backups automáticos: Configurar cron job diario

Solución de Problemas

Error: "extension 'vector' does not exist"

# Verificar imagen de Docker
docker-compose pull db
docker-compose down
docker-compose up -d db

# Verificar extensión
docker exec openccb-db-1 psql -U user -d openccb_cms \
  -c "SELECT * FROM pg_extension WHERE extname = 'vector';"

Error: "Ollama no responde"

# Verificar contenedor
docker ps | grep ollama

# Probar conexión
curl http://localhost:11434/api/tags

# Reiniciar
docker-compose restart ollama

Error: "Puerto 5432 en uso"

El script usa automáticamente el puerto 5433 si el 5432 está ocupado.

# Verificar qué usa el puerto
lsof -i :5432

# Cambiar a puerto 5433 en .env
DATABASE_URL=postgresql://user:password@localhost:5433/openccb

Error: "CORS en login/registro"

Verificar que el rate limiter NO esté aplicado a rutas de autenticación:

// services/cms-service/src/main.rs
// CORRECTO:
.protected_routes
    .route_layer(middleware::from_fn(org_extractor_middleware))
// NO agregar GovernorLayer aquí

Error: "Audio recording no funciona"

  1. Verificar HTTPS: El audio requiere contexto seguro

    # Localhost está OK
    # Producción requiere HTTPS
    
  2. Verificar permisos del navegador:

    • Chrome: chrome://settings/content/microphone
    • Firefox: about:preferences#privacy → Permisos
  3. Verificar logs:

    [AudioResponse] Requesting microphone access...
    [AudioResponse] Microphone access granted
    

Limpieza Completa

# Detener servicios
docker-compose down -v

# Eliminar volúmenes
docker volume rm openccb_db_data

# Reinstalar
./install.sh

Seguridad de certificados

No subas a git claves privadas ni artefactos ACME.

nginx/certs-data/
*.key
*.csr
*.crt

Si necesitas respaldar certificados, hazlo fuera del repositorio.

Logs y Debugging

# Ver logs de servicios
docker compose logs -f studio
docker compose logs -f experience
docker compose logs -f db

# Logs con filtro
docker compose logs -f experience | grep -i error

# Acceder a DB
docker exec -it openccb-db psql -U user -d openccb_cms

# Verificar health LMS interno (desde red Docker)
docker exec openccb-studio node -e "fetch('http://experience:3002/health').then(async r=>{console.log(r.status);console.log(await r.text())})"

# Verificar variables activas en experience
docker exec openccb-experience sh -lc 'echo DATABASE_URL=$DATABASE_URL; echo LMS_DATABASE_URL=$LMS_DATABASE_URL'

Si openccb-experience queda con localhost:5433 en DATABASE_URL/LMS_DATABASE_URL, recrear con DB interna Docker:

LMS_DATABASE_URL='postgresql://user:password@db:5432/openccb_lms' docker compose up -d --force-recreate experience

Comandos Útiles

# Health checks
curl http://localhost:3001/health
curl http://localhost:3002/health

# Generar JWT_SECRET
./generate_jwt_secret.sh

# Reset de sesión
./clear_session.sh

# Diagnóstico de auth
./diagnose_auth.sh

# Ver usuarios
docker exec openccb-db psql -U user -d openccb_cms \
  -c "SELECT email, role FROM users;"

# Ver organizaciones
docker exec openccb-db psql -U user -d openccb_cms \
  -c "SELECT name, api_key FROM organizations;"

# Smoke test de permisos de audio LMS
./scripts/smoke_audio_roles.sh

Recursos Adicionales

  • README.md: Características y arquitectura
  • roadmap.md: Hoja de ruta de desarrollo
  • OPTIMIZATIONS.md: Guía de optimizaciones implementadas
  • PGVECTOR_EMBEDDINGS.md: Guía de búsqueda semántica

Última actualización: Marzo 2026 Versión: OpenCCB 0.2.3