From 64924f99999a31e1c290f0a010ae6d6ce838f31b Mon Sep 17 00:00:00 2001 From: Cesar Mendivil Date: Sat, 1 Nov 2025 00:49:33 -0700 Subject: [PATCH] Applied new local config --- .env.production | 49 ++ .npmrc | 13 +- CLOUDFLARE-TUNNEL-CONFIG.md | 65 ++ CONFIG-ACCESO-PUBLICO.md | 65 ++ CONFIG-RED-LOCAL.md | 36 + DOMINIO-PROPIO-CONFIG.md | 107 +++ DUCKDNS-CONFIG.md | 72 ++ Dockerfile | 67 ++ EASYPANEL-COMPARACION.md | 52 ++ EASYPANEL-README.md | 113 ++++ EASYPANEL-SIMPLE.md | 164 +++++ EASYPANEL-TURN-SERVER.md | 104 +++ EASYPANEL-UDP-LIMITACIONES.md | 29 + EASYPANEL-VPS-HIBRIDO.md | 129 ++++ LIVEKIT-SELFHOST-SERVER.md | 180 +++++ LIVEKIT-TURN-CONFIG.md | 40 ++ ROUTER-CONFIG-LIVEKIT.md | 103 +++ UDP-FIREWALL-CONFIG.md | 106 +++ configure-livekit-domain.sh | 190 ++++++ configure-udp-ports.sh | 58 ++ configure-udp-security.sh | 136 ++++ deploy-easypanel.sh | 100 +++ deploy-livekit-selfhost.sh | 221 +++++++ deploy-local-with-udp.sh | 125 ++++ docker-compose-with-livekit.yml | 94 +++ docker-compose.yml | 70 ++ docs/javascript-snippets.md | 178 +++++ docs/typescript-snippets.md | 202 ++++++ fix-admin-login.sh | 68 ++ livekit-local.yaml | 46 ++ livekit.yaml | 41 ++ meet-ce/backend/.env.dev | 39 +- meet-ce/frontend/angular.json | 4 +- meet-ce/frontend/package.json | 2 +- .../shared-meet-components/package.json | 2 +- nginx.conf | 124 ++++ pnpm-lock.yaml | 618 ++---------------- pnpm-workspace.yaml | 14 +- restart-stack.sh | 63 ++ setup-livekit-ssl.sh | 96 +++ solution-admin-access.sh | 66 ++ 41 files changed, 3477 insertions(+), 574 deletions(-) create mode 100644 .env.production create mode 100644 CLOUDFLARE-TUNNEL-CONFIG.md create mode 100644 CONFIG-ACCESO-PUBLICO.md create mode 100644 CONFIG-RED-LOCAL.md create mode 100644 DOMINIO-PROPIO-CONFIG.md create mode 100644 DUCKDNS-CONFIG.md create mode 100644 Dockerfile create mode 100644 EASYPANEL-COMPARACION.md create mode 100644 EASYPANEL-README.md create mode 100644 EASYPANEL-SIMPLE.md create mode 100644 EASYPANEL-TURN-SERVER.md create mode 100644 EASYPANEL-UDP-LIMITACIONES.md create mode 100644 EASYPANEL-VPS-HIBRIDO.md create mode 100644 LIVEKIT-SELFHOST-SERVER.md create mode 100644 LIVEKIT-TURN-CONFIG.md create mode 100644 ROUTER-CONFIG-LIVEKIT.md create mode 100644 UDP-FIREWALL-CONFIG.md create mode 100755 configure-livekit-domain.sh create mode 100755 configure-udp-ports.sh create mode 100755 configure-udp-security.sh create mode 100755 deploy-easypanel.sh create mode 100755 deploy-livekit-selfhost.sh create mode 100755 deploy-local-with-udp.sh create mode 100644 docker-compose-with-livekit.yml create mode 100644 docker-compose.yml create mode 100644 docs/javascript-snippets.md create mode 100644 docs/typescript-snippets.md create mode 100755 fix-admin-login.sh create mode 100644 livekit-local.yaml create mode 100644 livekit.yaml create mode 100644 nginx.conf create mode 100755 restart-stack.sh create mode 100755 setup-livekit-ssl.sh create mode 100755 solution-admin-access.sh diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..4a5bd5e --- /dev/null +++ b/.env.production @@ -0,0 +1,49 @@ +# CONFIGURACIÓN PARA EASYPANEL + LIVEKIT SELF-HOSTED + +# =========================================== +# CONFIGURACIÓN BÁSICA +# =========================================== +NODE_ENV=production +MEET_LOG_LEVEL=info +MEET_BLOB_STORAGE_MODE=memory + +# =========================================== +# USUARIO ADMINISTRADOR +# =========================================== +ADMIN_USER=admin +ADMIN_PASSWORD=admin123 + +# =========================================== +# LIVEKIT SELF-HOSTED (RED LOCAL + PÚBLICO) +# =========================================== +# ✅ LiveKit corriendo en servidor dedicado +# ✅ Puertos UDP expuestos en router +# ✅ SSL/WSS configurado + +# URL de tu LiveKit self-hosted (cambiar por tu dominio/IP) +LIVEKIT_URL=wss://mi-livekit.duckdns.org +# O con IP fija: wss://TU_IP_PUBLICA:443 + +LIVEKIT_API_KEY=production-key +LIVEKIT_API_SECRET=tu-super-secret-de-32-caracteres-o-mas + +# =========================================== +# REDIS (OPCIONAL para EasyPanel) +# =========================================== +# Si quieres Redis también en EasyPanel +# REDIS_HOST=redis +# REDIS_PORT=6379 +# REDIS_PASSWORD=admin-redis + +# =========================================== +# ARQUITECTURA FINAL: +# =========================================== +# Internet → Router (Port Forward) → LiveKit Server (192.168.1.19) +# ↘ EasyPanel → OpenVidu Meet Backend +# +# Ventajas: +# ✅ Control total sobre LiveKit +# ✅ Sin costos mensuales externos +# ✅ Rendimiento en red local +# ✅ Acceso desde internet +# ✅ Escalable según hardware \ No newline at end of file diff --git a/.npmrc b/.npmrc index 6234600..a18c482 100644 --- a/.npmrc +++ b/.npmrc @@ -1,10 +1,18 @@ +# Docker/CI specific npm configuration +# This configuration is used during Docker builds and CI workflows +# to prevent linking workspace packages and use published versions instead + +# Disable workspace package linking +# This forces pnpm to install packages from registry or local tarballs +link-workspace-packages=false + # Strict peer dependencies strict-peer-dependencies=false # Auto install peers auto-install-peers=true -# Shamefully hoist - neccessary for some packages +# Shamefully hoist - necessary for some packages shamefully-hoist=true # Node linker - use hoisted for full compatibility @@ -12,6 +20,3 @@ node-linker=hoisted # Lockfile settings lockfile=true - -# Optional: Store location (uncomment if you want to customize) -# store-dir=.pnpm-store diff --git a/CLOUDFLARE-TUNNEL-CONFIG.md b/CLOUDFLARE-TUNNEL-CONFIG.md new file mode 100644 index 0000000..420319a --- /dev/null +++ b/CLOUDFLARE-TUNNEL-CONFIG.md @@ -0,0 +1,65 @@ +# CLOUDFLARE TUNNEL - SIN PORT FORWARDING + +## ☁️ Cloudflare Tunnel para LiveKit (Avanzado) + +### Ventajas: +- ✅ **Sin port forwarding** en router +- ✅ **SSL automático** +- ✅ **Protección DDoS** +- ✅ **IP oculta** + +### ⚠️ Limitaciones para WebRTC: +- ❌ **UDP no soportado** directamente +- ⚠️ **Requiere TURN server** para WebRTC +- 🔧 **Solo TCP/HTTP** a través del tunnel + +### Configuración (solo si tienes TURN server): + +#### Paso 1: Instalar cloudflared +```bash +# Descargar cloudflared +curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb +sudo dpkg -i cloudflared.deb +``` + +#### Paso 2: Crear tunnel +```bash +# Login a Cloudflare +cloudflared tunnel login + +# Crear tunnel +cloudflared tunnel create livekit-tunnel + +# Configurar tunnel +cat > ~/.cloudflared/config.yml << 'EOF' +tunnel: livekit-tunnel +credentials-file: /home/usuario/.cloudflared/livekit-tunnel.json + +ingress: + - hostname: livekit.midominio.com + service: http://localhost:7880 + - service: http_status:404 +EOF + +# Crear DNS record +cloudflared tunnel route dns livekit-tunnel livekit.midominio.com + +# Ejecutar tunnel +cloudflared tunnel run livekit-tunnel +``` + +#### Configuración LiveKit (necesita TURN): +```yaml +# livekit-production.yaml +rtc: + # SIN puertos UDP directos - usar TURN + use_external_ip: false + + ice_servers: + - urls: ["stun:stun.l.google.com:19302"] + - urls: ["turn:turn.midominio.com:3478"] + username: "usuario" + credential: "password" +``` + +### ⚠️ **NO RECOMENDADO** para LiveKit porque WebRTC necesita UDP \ No newline at end of file diff --git a/CONFIG-ACCESO-PUBLICO.md b/CONFIG-ACCESO-PUBLICO.md new file mode 100644 index 0000000..e6a7bdb --- /dev/null +++ b/CONFIG-ACCESO-PUBLICO.md @@ -0,0 +1,65 @@ +# CONFIGURACIÓN AVANZADA: ACCESO DESDE INTERNET + +## 🌍 Para usuarios externos (más complejo y riesgoso) + +### ⚠️ PROBLEMAS de exponer UDP públicamente: + +1. **Seguridad**: 10,000 puertos UDP expuestos +2. **Complejidad**: Port forwarding masivo +3. **NAT Traversal**: Problemas con diferentes ISPs +4. **Mantenimiento**: Configuración de router compleja + +### Si NECESITAS acceso externo, opciones: + +#### Opción A: TURN Server (RECOMENDADO) +```yaml +# livekit-public.yaml +rtc: + use_external_ip: true + external_ip: "TU_IP_PUBLICA" + + # Usar TURN para atravesar NAT + ice_servers: + - urls: ["stun:stun.l.google.com:19302"] + - urls: ["turn:tu-turn-server.com:3478"] + username: "usuario" + credential: "password" + + # Rango reducido de puertos + port_range_start: 50000 + port_range_end: 50100 # Solo 100 puertos +``` + +#### Opción B: LiveKit Cloud (MÁS RECOMENDADO) +```env +# .env.production +LIVEKIT_URL=wss://tu-proyecto.livekit.cloud +LIVEKIT_API_KEY=cloud-api-key +LIVEKIT_API_SECRET=cloud-secret + +# ✅ SIN configuración UDP local +# ✅ Sin port forwarding +# ✅ Infraestructura optimizada +``` + +#### Opción C: VPN (Para usuarios conocidos) +```bash +# Configurar WireGuard/OpenVPN +# Usuarios se conectan por VPN a tu red local +# Acceso como si fueran locales + +# No requiere exponer UDP públicamente +# Acceso seguro y controlado +``` + +### Port Forwarding (Solo si es absolutamente necesario): +``` +⚠️ EN ROUTER: +UDP 50000-60000 → 192.168.1.19:50000-60000 + +❌ RIESGOS: +- 10,000 puertos UDP expuestos +- Posibles ataques DDoS +- Configuración compleja +- Problemas con CGN/CGNAT de ISPs +``` \ No newline at end of file diff --git a/CONFIG-RED-LOCAL.md b/CONFIG-RED-LOCAL.md new file mode 100644 index 0000000..bf03494 --- /dev/null +++ b/CONFIG-RED-LOCAL.md @@ -0,0 +1,36 @@ +# CONFIGURACIÓN RECOMENDADA: SOLO RED LOCAL + +## 🔒 Para uso en red local ÚNICAMENTE + +### Firewall UFW (SOLO red local): +```bash +# Permitir desde red local solamente +sudo ufw allow from 192.168.1.0/24 to any port 50000:60000 proto udp +sudo ufw allow from 192.168.1.0/24 to any port 7880 proto tcp +sudo ufw allow from 192.168.1.0/24 to any port 80 proto tcp + +# BLOQUEAR acceso externo a UDP +sudo ufw deny 50000:60000/udp + +# Verificar que solo red local tenga acceso +sudo ufw status numbered +``` + +### Router/Modem (NO configurar port forwarding): +``` +❌ NO hacer port forwarding de UDP 50000-60000 +✅ Solo HTTP (puerto 80) si necesitas acceso web externo +✅ Usar VPN si necesitas acceso remoto +``` + +### Ventajas: +- ✅ **Seguridad**: UDP no expuesto a internet +- ✅ **Simplicidad**: Sin configuración de router +- ✅ **Rendimiento**: Conexión directa en LAN +- ✅ **Sin NAT**: Sin problemas de traversal + +### Casos de uso: +- Oficina local +- Casa/familia +- Reuniones internas +- Desarrollo y testing \ No newline at end of file diff --git a/DOMINIO-PROPIO-CONFIG.md b/DOMINIO-PROPIO-CONFIG.md new file mode 100644 index 0000000..209576e --- /dev/null +++ b/DOMINIO-PROPIO-CONFIG.md @@ -0,0 +1,107 @@ +# CONFIGURACIÓN DOMINIO PROPIO PARA LIVEKIT + +## 🏠 Dominio propio (ej: livekit.midominio.com) + +### Opción A: Subdominio de tu dominio existente + +#### Paso 1: Configurar DNS +``` +Tipo: A +Nombre: livekit +Valor: TU_IP_PUBLICA +TTL: 300 + +Resultado: livekit.midominio.com → TU_IP_PUBLICA +``` + +#### Paso 2: Port forwarding en router +``` +Puerto 80 → 192.168.1.19:80 # HTTP para Let's Encrypt +Puerto 443 → 192.168.1.19:443 # HTTPS/WSS +Puerto 7880 → 192.168.1.19:7880 # LiveKit API directo +Puerto 50000-50100 (UDP) → 192.168.1.19:50000-50100 # WebRTC +``` + +#### Paso 3: SSL con Let's Encrypt +```bash +# Instalar certbot +sudo apt update +sudo apt install certbot nginx + +# Configurar Nginx básico +sudo tee /etc/nginx/sites-available/livekit << 'EOF' +server { + listen 80; + server_name livekit.midominio.com; + + location /.well-known/acme-challenge/ { + root /var/www/html; + } + + location / { + return 301 https://$server_name$request_uri; + } +} +EOF + +sudo ln -s /etc/nginx/sites-available/livekit /etc/nginx/sites-enabled/ +sudo nginx -t && sudo systemctl restart nginx + +# Generar certificado SSL +sudo certbot --nginx -d livekit.midominio.com + +# Resultado: certificados en /etc/letsencrypt/live/livekit.midominio.com/ +``` + +#### Paso 4: Configurar Nginx para LiveKit +```nginx +# /etc/nginx/sites-available/livekit +server { + listen 443 ssl http2; + server_name livekit.midominio.com; + + ssl_certificate /etc/letsencrypt/live/livekit.midominio.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/livekit.midominio.com/privkey.pem; + + # WebSocket proxy para LiveKit + location / { + proxy_pass http://localhost:7880; + 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; + + # Timeouts para WebRTC + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } +} + +server { + listen 80; + server_name livekit.midominio.com; + return 301 https://$server_name$request_uri; +} +``` + +#### Paso 5: Auto-renovación SSL +```bash +# Agregar a crontab +sudo crontab -e + +# Renovar certificados automáticamente +0 12 * * * /usr/bin/certbot renew --quiet && systemctl reload nginx +``` + +### URLs finales: +- **LiveKit WSS**: `wss://livekit.midominio.com` +- **API HTTPS**: `https://livekit.midominio.com` + +### Configurar en OpenVidu Meet: +```env +LIVEKIT_URL=wss://livekit.midominio.com +``` \ No newline at end of file diff --git a/DUCKDNS-CONFIG.md b/DUCKDNS-CONFIG.md new file mode 100644 index 0000000..0ee7685 --- /dev/null +++ b/DUCKDNS-CONFIG.md @@ -0,0 +1,72 @@ +# CONFIGURACIÓN DUCKDNS PARA LIVEKIT + +## 🦆 DuckDNS - Dominio gratuito para IP dinámica + +### Paso 1: Registrarse en DuckDNS +1. Ir a [duckdns.org](https://www.duckdns.org) +2. Login con Google/GitHub +3. Crear subdominio: `mi-livekit.duckdns.org` +4. Copiar el token + +### Paso 2: Script de actualización automática +```bash +# Crear script de actualización +cat > /home/xesar/update-duckdns.sh << 'EOF' +#!/bin/bash +# Actualizar DuckDNS con IP actual + +DOMAIN="mi-livekit" # Tu subdominio sin .duckdns.org +TOKEN="tu-token-aqui" # Token de DuckDNS + +# Obtener IP pública actual +CURRENT_IP=$(curl -s https://checkip.amazonaws.com) + +# Actualizar DuckDNS +RESPONSE=$(curl -s "https://www.duckdns.org/update?domains=$DOMAIN&token=$TOKEN&ip=$CURRENT_IP") + +if [ "$RESPONSE" = "OK" ]; then + echo "$(date): DuckDNS actualizado - $DOMAIN.duckdns.org → $CURRENT_IP" +else + echo "$(date): ERROR actualizando DuckDNS: $RESPONSE" +fi +EOF + +chmod +x /home/xesar/update-duckdns.sh +``` + +### Paso 3: Automatizar con cron +```bash +# Editar crontab +crontab -e + +# Agregar línea para actualizar cada 5 minutos: +*/5 * * * * /home/xesar/update-duckdns.sh >> /home/xesar/duckdns.log 2>&1 +``` + +### Paso 4: Configurar LiveKit con dominio +```yaml +# livekit-production.yaml +rtc: + external_ip: "mi-livekit.duckdns.org" # Tu dominio DuckDNS + port_range_start: 50000 + port_range_end: 50100 +``` + +### Paso 5: Port forwarding en router +``` +Regla: LiveKit-API +- Puerto externo: 7880 +- Puerto interno: 7880 +- IP: 192.168.1.19 +- Protocolo: TCP + +Regla: LiveKit-WebRTC +- Puerto externo: 50000-50100 +- Puerto interno: 50000-50100 +- IP: 192.168.1.19 +- Protocolo: UDP +``` + +### URLs finales: +- **LiveKit API**: `ws://mi-livekit.duckdns.org:7880` +- **Con SSL**: `wss://mi-livekit.duckdns.org:443` (después de configurar SSL) \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..10f5c59 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,67 @@ +# Multi-stage build para OpenVidu Meet +FROM node:20-alpine AS builder + +# Instalar pnpm +RUN npm install -g pnpm + +# Copiar archivos del workspace +WORKDIR /app +COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ +COPY meet-ce/backend/package.json ./meet-ce/backend/ +COPY meet-ce/frontend/package.json ./meet-ce/frontend/ +COPY meet-ce/frontend/projects/shared-meet-components/package.json ./meet-ce/frontend/projects/shared-meet-components/ + +# Instalar dependencias +RUN pnpm install --frozen-lockfile + +# Copiar código fuente +COPY . . + +# Build backend +WORKDIR /app/meet-ce/backend +RUN pnpm run build + +# Build frontend +WORKDIR /app/meet-ce/frontend +RUN pnpm run build:prod + +# Imagen de producción +FROM node:20-alpine AS production + +# Instalar pnpm +RUN npm install -g pnpm + +# Crear usuario no-root +RUN addgroup -g 1001 -S nodejs && \ + adduser -S openvidu -u 1001 + +WORKDIR /app + +# Copiar package.json y dependencias +COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ +COPY meet-ce/backend/package.json ./meet-ce/backend/ + +# Instalar solo dependencias de producción +RUN pnpm install --prod --frozen-lockfile + +# Copiar archivos compilados +COPY --from=builder /app/meet-ce/backend/dist ./meet-ce/backend/dist +COPY --from=builder /app/meet-ce/backend/public ./meet-ce/backend/public + +# Cambiar propietario +RUN chown -R openvidu:nodejs /app + +USER openvidu + +# Variables de entorno por defecto +ENV NODE_ENV=production +ENV PORT=6080 +ENV MEET_BLOB_STORAGE_MODE=memory +ENV MEET_LOG_LEVEL=info + +# Exponer puerto +EXPOSE 6080 + +# Comando de inicio +WORKDIR /app/meet-ce/backend +CMD ["node", "dist/src/server.js"] \ No newline at end of file diff --git a/EASYPANEL-COMPARACION.md b/EASYPANEL-COMPARACION.md new file mode 100644 index 0000000..7ca306b --- /dev/null +++ b/EASYPANEL-COMPARACION.md @@ -0,0 +1,52 @@ +# COMPARACIÓN: OPCIONES PARA EASYPANEL + +## 📊 Tabla comparativa + +| Opción | Configuración UDP | Costo | Complejidad | Rendimiento | Recomendado | +|--------|------------------|-------|-------------|-------------|-------------| +| **LiveKit Cloud** | ❌ No necesario | $20-100/mes | ⭐ Muy fácil | ⭐⭐⭐ Excelente | ✅ **SÍ** | +| **VPS Híbrido** | ✅ En VPS separado | $10-30/mes | ⭐⭐ Medio | ⭐⭐⭐ Excelente | ⚠️ Si budget limitado | +| **TURN Server** | ✅ 3 puertos en VPS | $5-15/mes | ⭐⭐⭐ Complejo | ⭐⭐ Bueno | ⚠️ Para expertos | +| **EasyPanel Solo** | ❌ Imposible | $0 extra | ❌ No funciona | ❌ No WebRTC | ❌ NO | + +## 🏆 RECOMENDACIÓN FINAL + +### Para la mayoría de casos: **LiveKit Cloud** + +```env +# .env.production para EasyPanel +LIVEKIT_URL=wss://tu-proyecto.livekit.cloud +LIVEKIT_API_KEY=api-key-de-cloud +LIVEKIT_API_SECRET=secret-de-cloud +``` + +### Ventajas de LiveKit Cloud: +- ✅ **Cero configuración UDP** +- ✅ **Sin VPS adicionales** +- ✅ **Infraestructura global** +- ✅ **Escalabilidad automática** +- ✅ **Soporte oficial** +- ✅ **TURN servers incluidos** +- ✅ **Monitoreo y analytics** + +### Costos LiveKit Cloud: +- **Free tier**: 50GB/mes gratis +- **Starter**: $20/mes - 500GB +- **Pro**: $99/mes - 2TB + features + +### Setup LiveKit Cloud: +1. **Registro**: https://cloud.livekit.io +2. **Crear proyecto** +3. **Copiar credenciales** +4. **Configurar en EasyPanel** +5. **Deploy** ✅ + +## 🎯 PASOS SIGUIENTE PARA TI + +¿Qué opción prefieres? + +1. **LiveKit Cloud** (fácil, costo medio) +2. **VPS Híbrido** (control total, setup complejo) +3. **TURN Server** (experto, costo bajo) + +Te ayudo a configurar la que elijas. \ No newline at end of file diff --git a/EASYPANEL-README.md b/EASYPANEL-README.md new file mode 100644 index 0000000..738cbd6 --- /dev/null +++ b/EASYPANEL-README.md @@ -0,0 +1,113 @@ +# CONFIGURACIÓN EASYPANEL - OpenVidu Meet +# ======================================== + +## 📋 CONFIGURACIÓN DEL PROYECTO + +### 1. Crear Proyecto en EasyPanel +- Tipo: Docker Compose o Docker Build +- Repositorio: Tu repo con estos archivos +- Branch: main + +### 2. Variables de Entorno Requeridas +```env +# Básicas +NODE_ENV=production +MEET_LOG_LEVEL=info +MEET_BLOB_STORAGE_MODE=memory + +# Admin (CAMBIAR) +ADMIN_PASSWORD=tu-password-seguro-aqui + +# LiveKit (ajustar según tu setup) +LIVEKIT_URL=wss://tu-livekit-domain.com +LIVEKIT_API_KEY=tu-api-key +LIVEKIT_API_SECRET=tu-secret-32-caracteres-minimo + +# Proxy +TRUST_PROXY=true +SERVER_CORS_ORIGIN=* +USE_HTTPS=true +``` + +### 3. Configuración de Puertos +- **Opción A (con Nginx)**: Puerto 80 +- **Opción B (directo)**: Puerto 6080 + +### 4. Configuración de Dominio +- Agregar tu dominio en EasyPanel +- Habilitar SSL automático +- Configurar redirects HTTP → HTTPS + +## 🐳 OPCIONES DE DEPLOY + +### Opción A: Con Nginx Proxy (Recomendado) +```yaml +# Usar docker-compose.yml completo +# Puerto expuesto: 80/443 +# Incluye rate limiting y optimizaciones +``` + +### Opción B: Solo Backend +```yaml +# Solo el servicio openvidu-meet del compose +# Puerto expuesto: 6080 +# EasyPanel maneja el proxy +``` + +## 🔧 CONFIGURACIONES ADICIONALES + +### LiveKit Setup +1. Desplegar LiveKit en servidor separado +2. Configurar LIVEKIT_URL con dominio público +3. Generar API keys seguros + +### Redis (Opcional) +- Usar servicio Redis de EasyPanel +- O mantener storage en memoria para simplicidad + +### SSL/TLS +- EasyPanel maneja certificados automáticamente +- Configurar HTTPS en variables de entorno + +## 🚨 CONSIDERACIONES DE SEGURIDAD + +1. **Cambiar credenciales por defecto** +2. **Usar secrets seguros para LiveKit** +3. **Configurar CORS apropiadamente** +4. **Habilitar rate limiting** +5. **Usar HTTPS únicamente** + +## 📊 MONITOREO + +### Health Checks +- `/nginx-health` - Estado del proxy +- `/api/health` - Estado del backend +- Logs en EasyPanel dashboard + +### Métricas +- CPU/Memory usage +- Response times +- Error rates + +## 🔄 ACTUALIZACIONES + +1. Push cambios al repo +2. EasyPanel rebuilds automáticamente +3. Zero-downtime deployment + +## 🐛 TROUBLESHOOTING + +### Backend no arranca +- Verificar variables de entorno +- Revisar logs en EasyPanel +- Verificar puertos + +### Error de proxy +- Verificar nginx.conf +- Revisar headers +- Verificar upstreams + +### LiveKit no conecta +- Verificar LIVEKIT_URL +- Verificar API keys +- Verificar connectivity \ No newline at end of file diff --git a/EASYPANEL-SIMPLE.md b/EASYPANEL-SIMPLE.md new file mode 100644 index 0000000..b15ede7 --- /dev/null +++ b/EASYPANEL-SIMPLE.md @@ -0,0 +1,164 @@ +# 🚀 **DEPLOYMENT EN EASYPANEL - SIMPLIFICADO** + +## 📋 **RESUMEN DE CONFIGURACIÓN** + +✅ **EasyPanel maneja automáticamente:** +- SSL/TLS con certificados gratuitos +- Subdominios (ej: `tu-app.easypanel.host`) +- Proxy reverso con Traefik +- HTTPS redirect + +✅ **Tu aplicación expone:** +- Solo puerto 80 (HTTP) +- Nginx como proxy interno +- OpenVidu Meet backend + +--- + +## 🔧 **PASOS DE DEPLOYMENT** + +### **1. Preparar archivos** +```bash +# Los archivos ya están listos: +# ✅ Dockerfile (optimizado) +# ✅ docker-compose.yml (puerto 80 solamente) +# ✅ nginx.conf (sin SSL - solo HTTP) +# ✅ .env.production (variables de entorno) +``` + +### **2. Subir a repositorio Git** +```bash +git add Dockerfile docker-compose.yml nginx.conf .env.production +git commit -m "Add EasyPanel deployment config" +git push +``` + +### **3. Crear proyecto en EasyPanel** + +#### **Opción A: Docker Compose (Recomendado)** +1. **Nuevo Proyecto** → **Deploy from Git** +2. **Conectar repositorio** +3. **Tipo:** Docker Compose +4. **Archivo:** `docker-compose.yml` +5. **Puerto expuesto:** `80` + +#### **Opción B: Dockerfile simple** +1. **Nuevo Proyecto** → **Deploy from Git** +2. **Tipo:** Dockerfile +3. **Puerto:** `6080` +4. **Health Check:** `/health` + +### **4. Variables de entorno en EasyPanel** + +En el dashboard de EasyPanel, configurar: + +```env +# ADMIN (¡CAMBIAR!) +ADMIN_PASSWORD=mi-password-super-seguro + +# LIVEKIT (configurar según tu setup) +LIVEKIT_URL=wss://tu-livekit-domain.com +LIVEKIT_API_KEY=tu-api-key +LIVEKIT_API_SECRET=tu-secret-de-32-caracteres + +# REDIS (opcional) +REDIS_HOST=tu-redis-host +REDIS_PASSWORD=tu-redis-password +``` + +### **5. Deploy** +- Hacer clic en **Deploy** +- EasyPanel construirá automáticamente +- Generará subdominio (ej: `openvidu-meet.easypanel.host`) +- Aplicará SSL automáticamente + +--- + +## 🌐 **RESULTADO FINAL** + +``` +https://tu-app.easypanel.host +├── EasyPanel Traefik Proxy (SSL/HTTPS) +└── Tu Container (puerto 80) + ├── Nginx (proxy interno) + └── OpenVidu Meet Backend (:6080) +``` + +### **URLs disponibles:** +- **Aplicación:** `https://tu-app.easypanel.host` +- **Admin Login:** `https://tu-app.easypanel.host/admin` +- **API:** `https://tu-app.easypanel.host/api/` +- **Health Check:** `https://tu-app.easypanel.host/health` + +--- + +## 🔧 **CONFIGURACIÓN LIVEKIT** + +Para que funcione completamente, necesitas **LiveKit server** separado: + +### **Opción 1: LiveKit en EasyPanel (otro proyecto)** +```yaml +# livekit.yaml para EasyPanel +port: 7880 +redis: + address: tu-redis:6379 + password: tu-password +``` + +### **Opción 2: LiveKit Cloud** +- Registrarse en [LiveKit Cloud](https://cloud.livekit.io) +- Copiar `LIVEKIT_URL`, `API_KEY`, `API_SECRET` +- Configurar en variables de entorno + +--- + +## 🔐 **SEGURIDAD** + +### **Cambiar credenciales por defecto:** +```env +ADMIN_PASSWORD=un-password-muy-seguro +LIVEKIT_API_SECRET=secret-de-al-menos-32-caracteres +``` + +### **Headers de seguridad incluidos:** +- Rate limiting (API: 10req/s, Login: 1req/s) +- X-Frame-Options +- X-Content-Type-Options +- X-XSS-Protection + +--- + +## 🚨 **TROUBLESHOOTING** + +### **El container no inicia:** +```bash +# Ver logs en EasyPanel dashboard +# O conectar por SSH: +docker logs container-name +``` + +### **502 Bad Gateway:** +- Verificar que el backend responde en puerto 6080 +- Health check: `curl localhost:6080/health` + +### **WebSocket no funciona:** +- Verificar configuración de LiveKit +- Headers de WebSocket están configurados en nginx + +### **Admin login no funciona:** +- Verificar variable `ADMIN_PASSWORD` +- Limpiar datos Redis si está configurado + +--- + +## ✅ **CHECKLIST FINAL** + +- [ ] Repository con archivos de deployment subido +- [ ] Proyecto creado en EasyPanel +- [ ] Variables de entorno configuradas +- [ ] Password admin cambiado +- [ ] LiveKit configurado (separado) +- [ ] SSL funcionando automáticamente +- [ ] Admin login funcional en `/admin` + +**¡Ya tienes OpenVidu Meet funcionando en producción con EasyPanel!** 🎉 \ No newline at end of file diff --git a/EASYPANEL-TURN-SERVER.md b/EASYPANEL-TURN-SERVER.md new file mode 100644 index 0000000..108fd48 --- /dev/null +++ b/EASYPANEL-TURN-SERVER.md @@ -0,0 +1,104 @@ +# SOLUCIÓN: TURN SERVER PARA EASYPANEL + +## 🔄 TURN Server como alternativa para NAT traversal + +### ¿Qué es TURN? +TURN (Traversal Using Relays around NAT) permite que WebRTC funcione sin exponer miles de puertos UDP. + +## 🏗️ ARQUITECTURA CON TURN + +``` +Cliente → Internet → TURN Server → EasyPanel + (3 puertos) (sin UDP) + +Vs. directo: +Cliente → Internet → EasyPanel + (10,000 UDP) ❌ No posible +``` + +## 📋 IMPLEMENTACIÓN + +### 1. TURN Server en VPS separado +```bash +# Instalar Coturn en VPS +apt-get update +apt-get install coturn + +# /etc/turnserver.conf +listening-port=3478 +tls-listening-port=5349 +external-ip=IP_PUBLICA_VPS +realm=turn.tu-dominio.com +lt-cred-mech +user=usuario:password123 +verbose +``` + +### 2. Firewall VPS (Solo 3 puertos) +```bash +# Solo estos 3 puertos para TURN +ufw allow 3478/tcp # TURN TCP +ufw allow 3478/udp # TURN UDP +ufw allow 5349/tcp # TURN over TLS +ufw enable +``` + +### 3. LiveKit en EasyPanel con TURN +```yaml +# livekit.yaml para EasyPanel +port: 7880 + +keys: + devkey: tu-secret-32-chars + +# SIN puertos UDP locales - usar TURN +rtc: + # NO port_range - usa TURN + use_external_ip: false + + # Configurar TURN servers + ice_servers: + - urls: ["stun:stun.l.google.com:19302"] + - urls: ["turn:turn.tu-dominio.com:3478"] + username: "usuario" + credential: "password123" + - urls: ["turns:turn.tu-dominio.com:5349"] + username: "usuario" + credential: "password123" +``` + +### 4. Variables EasyPanel +```env +# Solo TCP - SIN UDP +LIVEKIT_URL=wss://tu-app.easypanel.host/livekit +LIVEKIT_API_KEY=devkey +LIVEKIT_API_SECRET=tu-secret-32-chars +``` + +### 5. Nginx en EasyPanel para proxy LiveKit +```nginx +# nginx.conf - agregar ruta para LiveKit +location /livekit { + proxy_pass http://openvidu-meet:7880; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; +} +``` + +## 💰 COSTOS +- **TURN VPS**: $5-10/mes (pequeño VPS) +- **EasyPanel**: Tu plan actual +- **Total**: +$5-10/mes vs LiveKit Cloud + +## ✅ VENTAJAS +- ✅ Solo 3 puertos UDP en VPS externo +- ✅ EasyPanel sin UDP +- ✅ NAT traversal garantizado +- ✅ Menor costo que LiveKit Cloud + +## ❌ DESVENTAJAS +- ❌ Configuración más compleja +- ❌ VPS adicional para TURN +- ❌ Latencia adicional (relay) +- ❌ Ancho de banda TURN server \ No newline at end of file diff --git a/EASYPANEL-UDP-LIMITACIONES.md b/EASYPANEL-UDP-LIMITACIONES.md new file mode 100644 index 0000000..7b25ab5 --- /dev/null +++ b/EASYPANEL-UDP-LIMITACIONES.md @@ -0,0 +1,29 @@ +# LIMITACIONES DE EASYPANEL PARA UDP + +## ❌ Por qué EasyPanel NO puede exponer UDP: + +### Arquitectura de EasyPanel: +``` +Internet → Traefik (HTTP/HTTPS Proxy) → Tu Container + ↑ + Solo maneja TCP/HTTP/HTTPS + NO puede proxy UDP +``` + +### Limitaciones técnicas: +1. **Traefik**: Solo HTTP/HTTPS reverse proxy +2. **Docker networking**: Limitado a puertos TCP expuestos +3. **UI de EasyPanel**: Solo configuración HTTP +4. **Load balancing**: Diseñado para web apps, no media streaming + +### Puertos disponibles en EasyPanel: +- ✅ 80 (HTTP) +- ✅ 443 (HTTPS) +- ✅ Puertos TCP custom +- ❌ Puertos UDP (NO DISPONIBLE) + +## ⚠️ Problemas si intentas exponer UDP: +- EasyPanel UI no tiene opción para UDP +- Traefik no puede hacer proxy de UDP +- Docker compose limitado a TCP en EasyPanel +- No hay configuración de port ranges UDP \ No newline at end of file diff --git a/EASYPANEL-VPS-HIBRIDO.md b/EASYPANEL-VPS-HIBRIDO.md new file mode 100644 index 0000000..0dd9917 --- /dev/null +++ b/EASYPANEL-VPS-HIBRIDO.md @@ -0,0 +1,129 @@ +# SOLUCIÓN: LIVEKIT EN VPS SEPARADO + EASYPANEL + +## 🏗️ ARQUITECTURA HÍBRIDA + +``` +┌─ EasyPanel ────────────────┐ ┌─ VPS Separado ─────────┐ +│ │ │ │ +│ OpenVidu Meet Backend ──────────→ LiveKit Server │ +│ (HTTP/HTTPS only) │ │ (UDP 50000-60000) │ +│ │ │ │ +└────────────────────────────┘ └────────────────────────┘ + ↑ ↑ + Traefik/SSL Firewall/UDP abierto +``` + +## 📋 CONFIGURACIÓN PASO A PASO + +### 1. EasyPanel (Solo OpenVidu Meet Backend) +```yaml +# docker-compose.yml para EasyPanel +version: '3.8' +services: + openvidu-meet: + build: . + environment: + # LiveKit en VPS externo + LIVEKIT_URL: wss://livekit.tu-vps.com:7880 + LIVEKIT_API_KEY: devkey + LIVEKIT_API_SECRET: tu-secret-32-chars + ports: + - "80:6080" # Solo HTTP - EasyPanel maneja SSL +``` + +### 2. VPS Separado (Solo LiveKit + Redis) +```yaml +# docker-compose.yml en VPS +version: '3.8' +services: + livekit: + image: livekit/livekit-server:latest + ports: + - "7880:7880" # API/WebSocket + - "50000-60000:50000-60000/udp" # WebRTC + volumes: + - ./livekit.yaml:/livekit.yaml + command: --config /livekit.yaml + + redis: + image: redis:7-alpine + ports: + - "6379:6379" + command: redis-server --requirepass redispassword +``` + +### 3. Configuración LiveKit en VPS +```yaml +# livekit.yaml en VPS +port: 7880 +bind_addresses: ["0.0.0.0"] + +keys: + devkey: tu-secret-de-32-caracteres-minimo + +redis: + address: "localhost:6379" + password: "redispassword" + +rtc: + port_range_start: 50000 + port_range_end: 60000 + use_external_ip: true + external_ip: "IP_PUBLICA_DEL_VPS" + + ice_servers: + - urls: ["stun:stun.l.google.com:19302"] +``` + +### 4. Firewall en VPS +```bash +# Configurar firewall en VPS +ufw allow 7880/tcp # LiveKit API +ufw allow 50000:60000/udp # WebRTC UDP +ufw allow 6379/tcp # Redis (si acceso externo) +ufw enable +``` + +### 5. SSL para LiveKit (Nginx en VPS) +```nginx +# /etc/nginx/sites-available/livekit +server { + listen 443 ssl; + server_name livekit.tu-vps.com; + + ssl_certificate /path/to/cert.pem; + ssl_certificate_key /path/to/key.pem; + + location / { + proxy_pass http://localhost:7880; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + } +} +``` + +## 💰 COSTOS ESTIMADOS + +### VPS para LiveKit: +- **Básico**: $5-10/mes (2GB RAM, 1 CPU) +- **Medio**: $15-25/mes (4GB RAM, 2 CPU) +- **Alto**: $30-50/mes (8GB RAM, 4 CPU) + +### Proveedores recomendados: +- DigitalOcean +- Linode +- Hetzner +- Vultr + +## ✅ VENTAJAS +- ✅ EasyPanel para web app (fácil) +- ✅ VPS dedicado para WebRTC (potencia) +- ✅ Escalabilidad independiente +- ✅ Control total sobre LiveKit + +## ❌ DESVENTAJAS +- ❌ Costo adicional VPS +- ❌ Más complejidad de setup +- ❌ Mantenimiento de dos servicios \ No newline at end of file diff --git a/LIVEKIT-SELFHOST-SERVER.md b/LIVEKIT-SELFHOST-SERVER.md new file mode 100644 index 0000000..44d5309 --- /dev/null +++ b/LIVEKIT-SELFHOST-SERVER.md @@ -0,0 +1,180 @@ +# SERVIDOR LIVEKIT SELF-HOSTING DEDICADO + +## 🖥️ Setup en servidor dedicado (192.168.1.19) + +### Docker Compose para LiveKit Server: +```yaml +# docker-compose-livekit-server.yml +version: '3.8' + +services: + # LiveKit Server Principal + livekit-server: + image: livekit/livekit-server:latest + container_name: livekit-production + restart: unless-stopped + ports: + # API/WebSocket (EXPONER PÚBLICAMENTE) + - "7880:7880" + + # Rango UDP para WebRTC (EXPONER PÚBLICAMENTE) + - "50000-50100:50000-50100/udp" # 100 puertos para ~10 usuarios concurrentes + + volumes: + - ./livekit-production.yaml:/livekit.yaml:ro + - ./logs:/app/logs + command: --config /livekit.yaml + environment: + - LIVEKIT_CONFIG=/livekit.yaml + networks: + - livekit-network + depends_on: + - redis + + # Redis para LiveKit + redis: + image: redis:7-alpine + container_name: livekit-redis + restart: unless-stopped + ports: + - "6379:6379" + command: redis-server --requirepass ${REDIS_PASSWORD:-livekitredis123} + volumes: + - redis_data:/data + networks: + - livekit-network + + # Nginx SSL Termination (para HTTPS/WSS) + nginx-livekit: + image: nginx:alpine + container_name: livekit-nginx + restart: unless-stopped + ports: + - "443:443" # HTTPS/WSS (EXPONER PÚBLICAMENTE) + - "80:80" # HTTP redirect + volumes: + - ./nginx-livekit.conf:/etc/nginx/nginx.conf:ro + - ./ssl:/etc/nginx/ssl:ro # Certificados SSL + depends_on: + - livekit-server + networks: + - livekit-network + +volumes: + redis_data: + +networks: + livekit-network: + driver: bridge +``` + +### Configuración LiveKit Production: +```yaml +# livekit-production.yaml +port: 7880 +bind_addresses: ["0.0.0.0"] + +# API Keys seguros +keys: + production-key: tu-super-secret-de-32-caracteres-o-mas + +# Redis para scaling y persistence +redis: + address: "redis:6379" + password: "livekitredis123" + db: 0 + +# RTC Configuration para acceso público +rtc: + # Puertos UDP (coincidir con docker-compose) + port_range_start: 50000 + port_range_end: 50100 + + # IP pública/externa (tu IP pública o dominio) + use_external_ip: true + external_ip: "TU_IP_PUBLICA_O_DOMINIO" # ej: "mi-casa.duckdns.org" + + # STUN servers para NAT traversal + ice_servers: + - urls: ["stun:stun.l.google.com:19302"] + - urls: ["stun:stun1.l.google.com:19302"] + +# Room settings para producción +room: + auto_create: true + max_participants: 50 + empty_timeout: 600 # 10 minutos + +# Security +webhook: + # Opcional: webhook para eventos + api_key: "tu-webhook-key" + +# Logging +log_level: info +log_format: json + +# Enable egress (grabaciones) +# Automático con Redis +``` + +### Nginx SSL para LiveKit: +```nginx +# nginx-livekit.conf +events { + worker_connections 1024; +} + +http { + # Redirect HTTP to HTTPS + server { + listen 80; + server_name _; + return 301 https://$host$request_uri; + } + + # HTTPS/WSS Server + server { + listen 443 ssl http2; + server_name _; + + # SSL Configuration + ssl_certificate /etc/nginx/ssl/cert.pem; + ssl_certificate_key /etc/nginx/ssl/key.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + + # WebSocket support para LiveKit + location / { + proxy_pass http://livekit-server:7880; + 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; + + # Timeouts para WebRTC + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + } +} +``` + +## 🔥 Firewall en servidor LiveKit: +```bash +# UFW rules para exposición pública segura +sudo ufw allow 80/tcp comment "HTTP redirect" +sudo ufw allow 443/tcp comment "HTTPS/WSS LiveKit" +sudo ufw allow 7880/tcp comment "LiveKit API directo" +sudo ufw allow 50000:50100/udp comment "WebRTC UDP range" + +# Opcional: limitar SSH a red local solamente +sudo ufw allow from 192.168.1.0/24 to any port 22 + +sudo ufw enable +sudo ufw status numbered +``` \ No newline at end of file diff --git a/LIVEKIT-TURN-CONFIG.md b/LIVEKIT-TURN-CONFIG.md new file mode 100644 index 0000000..0886480 --- /dev/null +++ b/LIVEKIT-TURN-CONFIG.md @@ -0,0 +1,40 @@ +# CONFIGURACIÓN TURN PARA LIVEKIT + +## 🔧 Si necesitas TURN server para LiveKit detrás de firewall: + +### 1. Configurar Coturn (TURN server) +```bash +# Instalar coturn +apt-get install coturn + +# /etc/turnserver.conf +listening-port=3478 +tls-listening-port=5349 +external-ip=TU_IP_PUBLICA +realm=tu-dominio.com +lt-cred-mech +user=usuario:password +``` + +### 2. Configurar LiveKit con TURN +```yaml +# livekit.yaml +rtc: + port_range_start: 50000 + port_range_end: 60000 + ice_servers: + - urls: + - "stun:stun.l.google.com:19302" + - "turn:tu-turn-server.com:3478" + username: "usuario" + credential: "password" +``` + +### 3. Firewall para TURN +```bash +# Puertos necesarios +ufw allow 3478/tcp # TURN TCP +ufw allow 3478/udp # TURN UDP +ufw allow 5349/tcp # TURN TLS +ufw allow 50000:60000/udp # Media streams +``` \ No newline at end of file diff --git a/ROUTER-CONFIG-LIVEKIT.md b/ROUTER-CONFIG-LIVEKIT.md new file mode 100644 index 0000000..ddc2904 --- /dev/null +++ b/ROUTER-CONFIG-LIVEKIT.md @@ -0,0 +1,103 @@ +# CONFIGURACIÓN ROUTER - PORT FORWARDING PARA LIVEKIT + +## 🌐 Port Forwarding necesario en tu Router + +### Puertos a exponer públicamente: + +| Servicio | Puerto | Protocolo | IP Interna | Descripción | +|----------|---------|-----------|------------|-------------| +| **HTTP** | 80 | TCP | 192.168.1.19 | Redirect a HTTPS | +| **HTTPS/WSS** | 443 | TCP | 192.168.1.19 | LiveKit WebSocket Secure | +| **LiveKit API** | 7880 | TCP | 192.168.1.19 | API directa (opcional) | +| **WebRTC Media** | 50000-50100 | UDP | 192.168.1.19 | Streams de audio/video | + +### Configuración típica router: + +``` +Regla 1: LiveKit-HTTPS +- Servicio: HTTPS/Custom +- Puerto externo: 443 +- Puerto interno: 443 +- IP interna: 192.168.1.19 +- Protocolo: TCP +- Estado: Habilitado + +Regla 2: LiveKit-HTTP +- Servicio: HTTP +- Puerto externo: 80 +- Puerto interno: 80 +- IP interna: 192.168.1.19 +- Protocolo: TCP +- Estado: Habilitado + +Regla 3: LiveKit-WebRTC +- Servicio: Custom +- Puerto externo: 50000-50100 +- Puerto interno: 50000-50100 +- IP interna: 192.168.1.19 +- Protocolo: UDP +- Estado: Habilitado +``` + +## 🏠 IP Dinámica - Solución con DuckDNS + +### Si tu IP pública cambia (típico en casa): + +```bash +# 1. Crear cuenta en DuckDNS.org +# 2. Crear subdominio: mi-livekit.duckdns.org +# 3. Script de actualización automática + +# /home/usuario/update-duckdns.sh +#!/bin/bash +echo url="https://www.duckdns.org/update?domains=mi-livekit&token=TU_TOKEN&ip=" | curl -k -o ~/duckdns.log -K - + +# Crontab para actualizar cada 5 minutos +# crontab -e +*/5 * * * * /home/usuario/update-duckdns.sh >/dev/null 2>&1 +``` + +### Configurar dominio en LiveKit: +```yaml +# livekit-production.yaml +rtc: + external_ip: "mi-livekit.duckdns.org" # En lugar de IP +``` + +## 🔒 Certificado SSL automático con Let's Encrypt + +```bash +# Instalar certbot +sudo apt install certbot + +# Generar certificado para tu dominio +sudo certbot certonly --standalone -d mi-livekit.duckdns.org + +# Copiar certificados para Docker +sudo cp /etc/letsencrypt/live/mi-livekit.duckdns.org/fullchain.pem ./ssl/cert.pem +sudo cp /etc/letsencrypt/live/mi-livekit.duckdns.org/privkey.pem ./ssl/key.pem +sudo chown $USER:$USER ./ssl/*.pem + +# Auto-renovación (crontab) +0 12 * * * /usr/bin/certbot renew --quiet && docker-compose restart nginx-livekit +``` + +## 📊 Verificación de conectividad + +### Tests externos: +```bash +# Test puertos desde internet +nmap -p 80,443,7880 mi-livekit.duckdns.org +nmap -sU -p 50000-50010 mi-livekit.duckdns.org + +# Test WebSocket +wscat -c wss://mi-livekit.duckdns.org + +# Test HTTPS +curl -I https://mi-livekit.duckdns.org +``` + +### URLs finales: +- **LiveKit WSS**: `wss://mi-livekit.duckdns.org` +- **API HTTP**: `https://mi-livekit.duckdns.org` +- **Monitoreo**: `https://mi-livekit.duckdns.org/debug` \ No newline at end of file diff --git a/UDP-FIREWALL-CONFIG.md b/UDP-FIREWALL-CONFIG.md new file mode 100644 index 0000000..2718438 --- /dev/null +++ b/UDP-FIREWALL-CONFIG.md @@ -0,0 +1,106 @@ +# CONFIGURACIÓN MANUAL DE PUERTOS UDP PARA LIVEKIT + +## 🔥 FIREWALL UBUNTU/DEBIAN (UFW) +```bash +# Puertos TCP +sudo ufw allow 80/tcp comment "HTTP" +sudo ufw allow 6080/tcp comment "OpenVidu Meet" +sudo ufw allow 6379/tcp comment "Redis" +sudo ufw allow 7880/tcp comment "LiveKit API" + +# Puertos UDP para WebRTC +sudo ufw allow 50000:60000/udp comment "LiveKit WebRTC" + +# Verificar +sudo ufw status numbered +``` + +## 🔥 FIREWALL CENTOS/RHEL (firewalld) +```bash +# Puertos TCP +sudo firewall-cmd --permanent --add-port=80/tcp +sudo firewall-cmd --permanent --add-port=6080/tcp +sudo firewall-cmd --permanent --add-port=6379/tcp +sudo firewall-cmd --permanent --add-port=7880/tcp + +# Puertos UDP +sudo firewall-cmd --permanent --add-port=50000-60000/udp + +# Aplicar +sudo firewall-cmd --reload +sudo firewall-cmd --list-ports +``` + +## 🖥️ ROUTER/MODEM (Para acceso externo) +Si quieres acceso desde internet: + +### Port Forwarding necesario: +- **TCP 80** → Tu servidor (OpenVidu Meet) +- **TCP 7880** → Tu servidor (LiveKit API) +- **UDP 50000-60000** → Tu servidor (WebRTC media) + +### Configuración típica router: +``` +Servicio: OpenVidu-HTTP +Puerto externo: 80 +Puerto interno: 80 +IP interna: 192.168.1.19 +Protocolo: TCP + +Servicio: LiveKit-API +Puerto externo: 7880 +Puerto interno: 7880 +IP interna: 192.168.1.19 +Protocolo: TCP + +Servicio: WebRTC-Media +Puerto externo: 50000-60000 +Puerto interno: 50000-60000 +IP interna: 192.168.1.19 +Protocolo: UDP +``` + +## 🔍 VERIFICACIÓN DE PUERTOS + +### Verificar puertos abiertos: +```bash +# Ver todos los puertos TCP/UDP en uso +sudo ss -tulnp + +# Específicos de LiveKit +sudo ss -tulnp | grep -E "(7880|50000|60000)" + +# Verificar desde otro dispositivo +nmap -p 7880,50000-50010 192.168.1.19 +``` + +### Test de conectividad: +```bash +# Test TCP (LiveKit API) +curl http://192.168.1.19:7880 + +# Test WebSocket +wscat -c ws://192.168.1.19:7880 + +# Test UDP (requiere herramientas específicas) +nc -u 192.168.1.19 50000 +``` + +## ⚠️ CONSIDERACIONES IMPORTANTES + +### Para red local: +- ✅ Solo configurar firewall del servidor +- ✅ Usar IP local (192.168.x.x) +- ✅ No necesita port forwarding + +### Para acceso externo: +- ⚠️ Configurar port forwarding en router +- ⚠️ Usar IP pública o dominio +- ⚠️ Configurar HTTPS para LiveKit +- ⚠️ Considerar seguridad (VPN, etc.) + +### Rango de puertos UDP: +- **Mínimo:** 100 puertos (ej: 50000-50100) +- **Recomendado:** 1000 puertos (50000-51000) +- **Máximo configurado:** 10000 puertos (50000-60000) +- **Cálculo:** ~10 puertos por participante simultáneo \ No newline at end of file diff --git a/configure-livekit-domain.sh b/configure-livekit-domain.sh new file mode 100755 index 0000000..7119cf6 --- /dev/null +++ b/configure-livekit-domain.sh @@ -0,0 +1,190 @@ +#!/bin/bash +# Script para configurar dominio automáticamente para LiveKit + +set -e + +# Colores +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +echo -e "${BLUE}🌐 Configurador de Dominio para LiveKit${NC}" +echo "" + +# Detectar IP pública +echo "🔍 Detectando IP pública..." +PUBLIC_IP=$(curl -s https://checkip.amazonaws.com || curl -s https://ipinfo.io/ip || echo "No detectada") +LOCAL_IP=$(hostname -I | awk '{print $1}') + +echo -e "${BLUE}📊 Información de red:${NC}" +echo " IP Local: $LOCAL_IP" +echo " IP Pública: $PUBLIC_IP" +echo "" + +# Opciones de dominio +echo "¿Qué tipo de dominio quieres configurar?" +echo "1) DuckDNS (gratuito, IP dinámica)" +echo "2) Dominio propio + Let's Encrypt" +echo "3) Solo IP pública (sin dominio)" +echo "" +read -p "Selecciona opción (1-3): " DOMAIN_OPTION + +case $DOMAIN_OPTION in + 1) + echo -e "${GREEN}🦆 Configurando DuckDNS${NC}" + read -p "Subdominio DuckDNS (sin .duckdns.org): " DUCKDNS_SUBDOMAIN + read -p "Token DuckDNS: " DUCKDNS_TOKEN + + DOMAIN="$DUCKDNS_SUBDOMAIN.duckdns.org" + + # Crear script de actualización + cat > update-duckdns.sh << EOF +#!/bin/bash +CURRENT_IP=\$(curl -s https://checkip.amazonaws.com) +RESPONSE=\$(curl -s "https://www.duckdns.org/update?domains=$DUCKDNS_SUBDOMAIN&token=$DUCKDNS_TOKEN&ip=\$CURRENT_IP") +if [ "\$RESPONSE" = "OK" ]; then + echo "\$(date): DuckDNS actualizado - $DOMAIN → \$CURRENT_IP" +else + echo "\$(date): ERROR: \$RESPONSE" +fi +EOF + chmod +x update-duckdns.sh + + # Actualizar inmediatamente + ./update-duckdns.sh + + # Configurar cron + (crontab -l 2>/dev/null; echo "*/5 * * * * $(pwd)/update-duckdns.sh >> $(pwd)/duckdns.log 2>&1") | crontab - + + echo -e "${GREEN}✅ DuckDNS configurado: $DOMAIN${NC}" + LIVEKIT_URL="ws://$DOMAIN:7880" + ;; + + 2) + echo -e "${GREEN}🏠 Configurando dominio propio${NC}" + read -p "Dominio completo (ej: livekit.midominio.com): " CUSTOM_DOMAIN + + DOMAIN="$CUSTOM_DOMAIN" + + echo -e "${YELLOW}📋 Pasos manuales necesarios:${NC}" + echo "1. Configurar DNS A record:" + echo " $DOMAIN → $PUBLIC_IP" + echo "" + echo "2. Port forwarding en router:" + echo " TCP 80,443,7880 → $LOCAL_IP" + echo " UDP 50000-50100 → $LOCAL_IP" + echo "" + + read -p "¿Continuar con configuración SSL automática? (y/N): " SSL_SETUP + + if [[ $SSL_SETUP =~ ^[Yy]$ ]]; then + echo -e "${YELLOW}🔧 Configurando Nginx + SSL...${NC}" + + # Instalar dependencias + sudo apt update + sudo apt install -y nginx certbot python3-certbot-nginx + + # Configurar Nginx básico + sudo tee /etc/nginx/sites-available/livekit << EOF +server { + listen 80; + server_name $DOMAIN; + + location /.well-known/acme-challenge/ { + root /var/www/html; + } + + location / { + return 301 https://\$server_name\$request_uri; + } +} +EOF + + sudo ln -sf /etc/nginx/sites-available/livekit /etc/nginx/sites-enabled/ + sudo nginx -t && sudo systemctl restart nginx + + # Generar certificado + sudo certbot --nginx -d $DOMAIN --non-interactive --agree-tos --email admin@$DOMAIN + + echo -e "${GREEN}✅ SSL configurado para $DOMAIN${NC}" + fi + + LIVEKIT_URL="wss://$DOMAIN" + ;; + + 3) + echo -e "${YELLOW}📡 Usando IP pública directa${NC}" + DOMAIN="$PUBLIC_IP" + LIVEKIT_URL="ws://$PUBLIC_IP:7880" + ;; + + *) + echo -e "${RED}❌ Opción inválida${NC}" + exit 1 + ;; +esac + +# Actualizar configuración LiveKit +echo -e "${YELLOW}🔧 Actualizando configuración LiveKit...${NC}" + +# Actualizar livekit.yaml existente o crear nuevo +if [ -f "livekit-production.yaml" ]; then + sed -i "s/external_ip: .*/external_ip: \"$DOMAIN\"/" livekit-production.yaml + echo -e "${GREEN}✅ livekit-production.yaml actualizado${NC}" +elif [ -f "livekit.yaml" ]; then + sed -i "s/external_ip: .*/external_ip: \"$DOMAIN\"/" livekit.yaml + echo -e "${GREEN}✅ livekit.yaml actualizado${NC}" +else + echo -e "${YELLOW}⚠️ No se encontró archivo de configuración LiveKit${NC}" +fi + +# Actualizar variables para OpenVidu Meet +cat > .env.livekit-domain << EOF +# Configuración de dominio para LiveKit +DOMAIN=$DOMAIN +LIVEKIT_URL=$LIVEKIT_URL +PUBLIC_IP=$PUBLIC_IP +LOCAL_IP=$LOCAL_IP + +# Variables para EasyPanel/OpenVidu Meet: +LIVEKIT_URL=$LIVEKIT_URL +LIVEKIT_API_KEY=production-key +LIVEKIT_API_SECRET=tu-secret-de-32-caracteres +EOF + +echo -e "${GREEN}" +echo "=============================================" +echo "🎉 DOMINIO CONFIGURADO EXITOSAMENTE" +echo "=============================================" +echo "🌐 Dominio: $DOMAIN" +echo "🔗 LiveKit URL: $LIVEKIT_URL" +echo "📍 IP Pública: $PUBLIC_IP" +echo "🏠 IP Local: $LOCAL_IP" +echo "" +echo "📋 CONFIGURACIÓN PARA OPENVIDU MEET:" +echo " LIVEKIT_URL=$LIVEKIT_URL" +echo "" +echo "🔧 PUERTOS NECESARIOS EN ROUTER:" +echo " TCP 7880 → $LOCAL_IP:7880" +echo " UDP 50000-50100 → $LOCAL_IP:50000-50100" +if [[ $DOMAIN_OPTION == 2 ]]; then + echo " TCP 80,443 → $LOCAL_IP:80,443" +fi +echo "" +echo "📁 Archivos generados:" +echo " - .env.livekit-domain (variables)" +if [[ $DOMAIN_OPTION == 1 ]]; then + echo " - update-duckdns.sh (actualización automática)" +fi +echo "=============================================" +echo -e "${NC}" + +# Test conectividad +echo -e "${BLUE}🔍 Probando conectividad...${NC}" +if timeout 5 bash -c "echo >/dev/tcp/$DOMAIN/7880" 2>/dev/null; then + echo -e "${GREEN}✅ Puerto 7880 accesible${NC}" +else + echo -e "${YELLOW}⚠️ Puerto 7880 no accesible (verificar port forwarding)${NC}" +fi \ No newline at end of file diff --git a/configure-udp-ports.sh b/configure-udp-ports.sh new file mode 100755 index 0000000..1364f48 --- /dev/null +++ b/configure-udp-ports.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# Script para configurar puertos UDP para LiveKit local + +echo "🔧 Configurando puertos UDP para LiveKit..." + +# Verificar si ufw está disponible +if command -v ufw &> /dev/null; then + echo "Configurando con UFW..." + + # Puertos TCP para LiveKit API + sudo ufw allow 7880/tcp comment "LiveKit API" + + # Rango de puertos UDP para WebRTC (según livekit.yaml) + sudo ufw allow 50000:60000/udp comment "LiveKit WebRTC UDP" + + # Verificar reglas + echo "Reglas UFW configuradas:" + sudo ufw status numbered + +elif command -v firewall-cmd &> /dev/null; then + echo "Configurando con firewalld..." + + # Puerto TCP para LiveKit + sudo firewall-cmd --permanent --add-port=7880/tcp + + # Rango UDP para WebRTC + sudo firewall-cmd --permanent --add-port=50000-60000/udp + + # Recargar firewall + sudo firewall-cmd --reload + + echo "Reglas firewalld configuradas:" + sudo firewall-cmd --list-ports + +else + echo "⚠️ No se detectó UFW ni firewalld" + echo "Configurar manualmente:" + echo "- TCP 7880 (LiveKit API)" + echo "- UDP 50000-60000 (WebRTC media)" +fi + +echo "✅ Configuración de firewall completada" + +# Verificar que LiveKit esté corriendo +echo "🔍 Verificando LiveKit..." +if curl -s http://localhost:7880 > /dev/null 2>&1; then + echo "✅ LiveKit responde en puerto 7880" +else + echo "❌ LiveKit no responde - verificar que esté corriendo" +fi + +# Mostrar puertos abiertos +echo "📊 Puertos actualmente en uso:" +if command -v ss &> /dev/null; then + ss -tulnp | grep -E "(7880|50000|60000)" +elif command -v netstat &> /dev/null; then + netstat -tulnp | grep -E "(7880|50000|60000)" +fi \ No newline at end of file diff --git a/configure-udp-security.sh b/configure-udp-security.sh new file mode 100755 index 0000000..bc7f569 --- /dev/null +++ b/configure-udp-security.sh @@ -0,0 +1,136 @@ +#!/bin/bash +# Script para configurar UDP de forma segura según el caso de uso + +set -e + +# Colores +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +echo -e "${BLUE}🔧 Configuración segura de puertos UDP para LiveKit${NC}" +echo "" + +# Preguntar caso de uso +echo "¿Cuál es tu caso de uso?" +echo "1) Solo red local (recomendado y seguro)" +echo "2) Acceso desde internet (complejo y riesgoso)" +echo "3) Mostrar configuración actual" +echo "" +read -p "Selecciona opción (1-3): " OPTION + +case $OPTION in + 1) + echo -e "${GREEN}✅ Configurando para RED LOCAL únicamente${NC}" + + # Configurar firewall para solo red local + if command -v ufw &> /dev/null; then + echo "Configurando UFW para red local..." + + # Permitir desde red local + sudo ufw allow from 192.168.0.0/16 to any port 50000:60000 proto udp comment "LiveKit UDP (red local)" + sudo ufw allow from 192.168.0.0/16 to any port 7880 proto tcp comment "LiveKit API (red local)" + sudo ufw allow from 192.168.0.0/16 to any port 80 proto tcp comment "HTTP (red local)" + + # DENEGAR acceso externo a UDP + sudo ufw deny 50000:60000/udp comment "BLOQUEAR UDP externo" + + echo -e "${GREEN}✅ Firewall configurado para red local${NC}" + sudo ufw status numbered + + else + echo -e "${YELLOW}⚠️ UFW no disponible. Configurar manualmente:${NC}" + echo "- Permitir UDP 50000-60000 desde 192.168.x.x" + echo "- BLOQUEAR UDP desde internet" + fi + + echo "" + echo -e "${GREEN}🔒 CONFIGURACIÓN SEGURA APLICADA:${NC}" + echo "- UDP 50000-60000: Solo red local" + echo "- Acceso web: http://192.168.1.19" + echo "- Sin port forwarding necesario" + echo "- Máxima seguridad" + ;; + + 2) + echo -e "${RED}⚠️ CONFIGURACIÓN PARA ACCESO PÚBLICO${NC}" + echo "" + echo -e "${YELLOW}RIESGOS:${NC}" + echo "- 10,000 puertos UDP expuestos" + echo "- Posibles ataques de red" + echo "- Configuración compleja" + echo "- Problemas con NAT/CGNAT" + echo "" + echo -e "${BLUE}ALTERNATIVAS RECOMENDADAS:${NC}" + echo "1. LiveKit Cloud (sin UDP local)" + echo "2. VPN para usuarios remotos" + echo "3. TURN server para NAT traversal" + echo "" + read -p "¿Continuar con configuración pública? (y/N): " -n 1 -r + echo + + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo -e "${RED}Configurando acceso público...${NC}" + + if command -v ufw &> /dev/null; then + # Abrir UDP para todo el mundo (PELIGROSO) + sudo ufw allow 50000:60000/udp comment "LiveKit UDP PUBLICO" + sudo ufw allow 7880/tcp comment "LiveKit API PUBLICO" + sudo ufw allow 80/tcp comment "HTTP PUBLICO" + + echo -e "${RED}❌ UDP EXPUESTO PÚBLICAMENTE${NC}" + fi + + echo "" + echo -e "${RED}⚠️ CONFIGURACIÓN APLICADA (RIESGOSA):${NC}" + echo "- UDP 50000-60000: PÚBLICO" + echo "- Configurar port forwarding en router" + echo "- Usar IP pública en livekit.yaml" + echo "- Considerar VPN o LiveKit Cloud" + + else + echo -e "${GREEN}✅ Configuración pública cancelada${NC}" + fi + ;; + + 3) + echo -e "${BLUE}📊 Configuración actual:${NC}" + + # Verificar puertos UDP + echo "" + echo "Puertos UDP en uso:" + if command -v ss &> /dev/null; then + ss -ulnp | grep -E ":(5[0-9]{4})" | head -10 + fi + + # Verificar firewall + echo "" + echo "Reglas de firewall:" + if command -v ufw &> /dev/null; then + sudo ufw status numbered | grep -E "(50000|7880|80)" + fi + + # Verificar IP externa + echo "" + echo "IP externa detectada:" + curl -s ifconfig.me || echo "No disponible" + + echo "" + echo "IP local:" + hostname -I | awk '{print $1}' + ;; + + *) + echo -e "${RED}❌ Opción inválida${NC}" + exit 1 + ;; +esac + +echo "" +echo -e "${BLUE}💡 RECOMENDACIÓN FINAL:${NC}" +echo "Para máxima seguridad y simplicidad:" +echo "- Usar solo en red local" +echo "- Para acceso remoto: VPN o LiveKit Cloud" +echo "- NO exponer 10,000 puertos UDP públicamente" \ No newline at end of file diff --git a/deploy-easypanel.sh b/deploy-easypanel.sh new file mode 100755 index 0000000..eac131b --- /dev/null +++ b/deploy-easypanel.sh @@ -0,0 +1,100 @@ +#!/bin/bash +set -e + +echo "🚀 PREPARANDO DEPLOY PARA EASYPANEL" +echo "===================================" + +# 1. Crear directorio ssl +echo "1. Creando estructura de directorios..." +mkdir -p ssl logs + +# 2. Crear certificados dummy (EasyPanel los reemplazará) +echo "2. Creando certificados dummy..." +if [ ! -f ssl/cert.pem ]; then + openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout ssl/key.pem \ + -out ssl/cert.pem \ + -subj "/C=US/ST=State/L=City/O=Organization/CN=localhost" 2>/dev/null || \ + echo "⚠️ OpenSSL no disponible - EasyPanel manejará SSL" +fi + +# 3. Crear .dockerignore +echo "3. Optimizando build..." +cat > .dockerignore << 'EOF' +node_modules +.git +.env* +*.log +logs/ +ssl/ +*.md +.vscode +.idea +dist +coverage +.nyc_output +EOF + +# 4. Verificar archivos necesarios +echo "4. Verificando archivos..." +REQUIRED_FILES=( + "Dockerfile" + "docker-compose.yml" + "nginx.conf" + ".env.production" +) + +for file in "${REQUIRED_FILES[@]}"; do + if [ -f "$file" ]; then + echo " ✅ $file" + else + echo " ❌ $file - FALTANTE" + exit 1 + fi +done + +# 5. Test de build local (opcional) +echo "5. ¿Quieres probar el build localmente? (y/n)" +read -r TEST_BUILD + +if [ "$TEST_BUILD" = "y" ] || [ "$TEST_BUILD" = "Y" ]; then + echo "Construyendo imagen de prueba..." + docker build -t openvidu-meet-test . || { + echo "❌ Error en el build - revisar Dockerfile" + exit 1 + } + echo "✅ Build exitoso" +fi + +echo "" +echo "🎉 PREPARACIÓN COMPLETADA" +echo "=========================" +echo "" +echo "📋 PASOS PARA EASYPANEL:" +echo "" +echo "1. Crear nuevo proyecto en EasyPanel" +echo "2. Conectar repositorio Git" +echo "3. Configurar variables de entorno:" +echo " - Copiar contenido de .env.production" +echo " - Ajustar LIVEKIT_URL y secrets" +echo "" +echo "4. Configurar build:" +echo " - Dockerfile: ./Dockerfile" +echo " - Puerto: 80 (nginx) o 6080 (directo)" +echo "" +echo "5. Configurar dominio y SSL en EasyPanel" +echo "" +echo "📁 ARCHIVOS LISTOS:" +echo " ✅ Dockerfile (multi-stage optimizado)" +echo " ✅ docker-compose.yml (con nginx proxy)" +echo " ✅ nginx.conf (configuración completa)" +echo " ✅ .env.production (variables de ejemplo)" +echo "" +echo "🔗 URLs después del deploy:" +echo " • Admin: https://tu-dominio.com" +echo " • API: https://tu-dominio.com/api/" +echo " • Health: https://tu-dominio.com/nginx-health" +echo "" +echo "👤 Login por defecto:" +echo " • Usuario: admin" +echo " • Contraseña: [configurar en ADMIN_PASSWORD]" \ No newline at end of file diff --git a/deploy-livekit-selfhost.sh b/deploy-livekit-selfhost.sh new file mode 100755 index 0000000..a9fbb81 --- /dev/null +++ b/deploy-livekit-selfhost.sh @@ -0,0 +1,221 @@ +#!/bin/bash +# Script para desplegar LiveKit self-hosted con exposición pública + +set -e + +# Colores +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +echo -e "${BLUE}🏠 Configurando LiveKit Self-Hosted con exposición pública${NC}" +echo "" + +# Detectar IP local +LOCAL_IP=$(hostname -I | awk '{print $1}') +echo -e "${BLUE}🌐 IP Local detectada: $LOCAL_IP${NC}" + +# Preguntar dominio/IP pública +echo "¿Cuál es tu configuración de acceso público?" +echo "1) Tengo IP pública fija" +echo "2) IP dinámica - usar DuckDNS" +echo "3) Solo testing local" +echo "" +read -p "Selecciona opción (1-3): " IP_OPTION + +case $IP_OPTION in + 1) + read -p "Ingresa tu IP pública: " PUBLIC_IP + EXTERNAL_HOST="$PUBLIC_IP" + ;; + 2) + read -p "Ingresa tu subdominio DuckDNS (ej: mi-livekit): " DUCKDNS_SUBDOMAIN + EXTERNAL_HOST="$DUCKDNS_SUBDOMAIN.duckdns.org" + echo -e "${YELLOW}📝 Recuerda configurar DuckDNS token después${NC}" + ;; + 3) + EXTERNAL_HOST="$LOCAL_IP" + echo -e "${YELLOW}⚠️ Solo funcionará en red local${NC}" + ;; + *) + echo -e "${RED}❌ Opción inválida${NC}" + exit 1 + ;; +esac + +echo -e "${GREEN}🌐 Host externo configurado: $EXTERNAL_HOST${NC}" + +# Generar secretos seguros +API_SECRET=$(openssl rand -hex 32) +REDIS_PASSWORD=$(openssl rand -hex 16) + +echo -e "${YELLOW}🔧 Generando configuración...${NC}" + +# Crear directorio SSL +mkdir -p ssl logs + +# Generar livekit-production.yaml +cat > livekit-production.yaml << EOF +port: 7880 +bind_addresses: ["0.0.0.0"] + +# API Keys seguros (generados automáticamente) +keys: + production-key: $API_SECRET + +# Redis para persistence y scaling +redis: + address: "redis:6379" + password: "$REDIS_PASSWORD" + db: 0 + +# RTC Configuration para acceso público +rtc: + # Rango de puertos UDP reducido pero suficiente + port_range_start: 50000 + port_range_end: 50100 + + # Host/IP externa para acceso público + use_external_ip: true + external_ip: "$EXTERNAL_HOST" + + # STUN servers para NAT traversal + ice_servers: + - urls: ["stun:stun.l.google.com:19302"] + - urls: ["stun:stun1.l.google.com:19302"] + +# Room settings para producción +room: + auto_create: true + max_participants: 25 + empty_timeout: 600 + +# Logging para producción +log_level: info +log_format: json +EOF + +# Crear docker-compose-livekit-server.yml +cat > docker-compose-livekit-server.yml << EOF +version: '3.8' + +services: + livekit-server: + image: livekit/livekit-server:latest + container_name: livekit-production + restart: unless-stopped + ports: + - "7880:7880" + - "50000-50100:50000-50100/udp" + volumes: + - ./livekit-production.yaml:/livekit.yaml:ro + - ./logs:/app/logs + command: --config /livekit.yaml + networks: + - livekit-network + depends_on: + - redis + + redis: + image: redis:7-alpine + container_name: livekit-redis + restart: unless-stopped + ports: + - "6379:6379" + command: redis-server --requirepass $REDIS_PASSWORD + volumes: + - redis_data:/data + networks: + - livekit-network + +volumes: + redis_data: + +networks: + livekit-network: + driver: bridge +EOF + +# Crear variables para OpenVidu Meet +cat > .env.livekit-client << EOF +# Variables para EasyPanel/OpenVidu Meet +LIVEKIT_URL=ws://$EXTERNAL_HOST:7880 +LIVEKIT_API_KEY=production-key +LIVEKIT_API_SECRET=$API_SECRET +EOF + +echo -e "${GREEN}✅ Configuración generada${NC}" + +# Configurar firewall +echo -e "${YELLOW}🔥 Configurando firewall...${NC}" +if command -v ufw &> /dev/null; then + sudo ufw allow 7880/tcp comment "LiveKit API" + sudo ufw allow 50000:50100/udp comment "LiveKit WebRTC" + echo -e "${GREEN}✅ Firewall configurado${NC}" +fi + +# Parar servicios existentes +echo -e "${YELLOW}🛑 Parando servicios existentes...${NC}" +docker-compose -f docker-compose-livekit-server.yml down 2>/dev/null || true + +# Iniciar LiveKit Server +echo -e "${YELLOW}🚀 Iniciando LiveKit Server...${NC}" +docker-compose -f docker-compose-livekit-server.yml up -d + +# Esperar inicio +echo -e "${YELLOW}⏳ Esperando que LiveKit inicie...${NC}" +sleep 15 + +# Verificar servicios +echo -e "${BLUE}🔍 Verificando servicios...${NC}" + +if curl -s http://localhost:7880 > /dev/null 2>&1; then + echo -e "${GREEN}✅ LiveKit API funcionando${NC}" +else + echo -e "${RED}❌ LiveKit no responde${NC}" +fi + +if docker exec livekit-redis redis-cli -a $REDIS_PASSWORD ping > /dev/null 2>&1; then + echo -e "${GREEN}✅ Redis funcionando${NC}" +else + echo -e "${RED}❌ Redis no responde${NC}" +fi + +# Mostrar configuración final +echo -e "${GREEN}" +echo "=============================================" +echo "🎉 LIVEKIT SELF-HOSTED CONFIGURADO" +echo "=============================================" +echo "🌐 Host externo: $EXTERNAL_HOST" +echo "🔌 Puerto API: 7880" +echo "📡 Puertos UDP: 50000-50100" +echo "" +echo "📋 CONFIGURACIÓN PARA OPENVIDU MEET:" +echo " LIVEKIT_URL=ws://$EXTERNAL_HOST:7880" +echo " LIVEKIT_API_KEY=production-key" +echo " LIVEKIT_API_SECRET=$API_SECRET" +echo "" +echo "🔧 PASOS SIGUIENTES:" +echo "1. Configurar port forwarding en router:" +echo " - TCP 7880 → $LOCAL_IP:7880" +echo " - UDP 50000-50100 → $LOCAL_IP:50000-50100" +echo "" +if [[ $IP_OPTION == 2 ]]; then + echo "2. Configurar DuckDNS:" + echo " - Token en duckdns.org" + echo " - Script de actualización automática" + echo "" +fi +echo "3. Configurar OpenVidu Meet con variables generadas" +echo "4. (Opcional) Configurar SSL/HTTPS con Let's Encrypt" +echo "=============================================" +echo -e "${NC}" + +# Mostrar logs +read -p "¿Ver logs de LiveKit en tiempo real? (y/N): " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + docker-compose -f docker-compose-livekit-server.yml logs -f livekit-server +fi \ No newline at end of file diff --git a/deploy-local-with-udp.sh b/deploy-local-with-udp.sh new file mode 100755 index 0000000..35ae8cf --- /dev/null +++ b/deploy-local-with-udp.sh @@ -0,0 +1,125 @@ +#!/bin/bash +# Script completo para desplegar OpenVidu Meet con LiveKit local y UDP + +set -e + +echo "🚀 Desplegando OpenVidu Meet con LiveKit local (UDP)..." + +# Colores para output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Verificar Docker +if ! command -v docker &> /dev/null; then + echo -e "${RED}❌ Docker no está instalado${NC}" + exit 1 +fi + +if ! command -v docker-compose &> /dev/null; then + echo -e "${RED}❌ Docker Compose no está instalado${NC}" + exit 1 +fi + +# Obtener IP local +LOCAL_IP=$(hostname -I | awk '{print $1}') +echo -e "${BLUE}🌐 IP Local detectada: $LOCAL_IP${NC}" + +# Crear .env para local +echo -e "${YELLOW}📝 Creando configuración local...${NC}" +cat > .env.local << EOF +# Configuración LOCAL con LiveKit y UDP +ADMIN_PASSWORD=admin123 +REDIS_PASSWORD=redispassword + +# LiveKit Local +LIVEKIT_URL=ws://$LOCAL_IP:7880 +LIVEKIT_API_KEY=devkey +LIVEKIT_API_SECRET=secretsecretsecretsecretsecretsecret + +# Redis Local +REDIS_HOST=$LOCAL_IP +REDIS_PORT=6379 +EOF + +# Actualizar IP en livekit-local.yaml +echo -e "${YELLOW}🔧 Configurando LiveKit para IP $LOCAL_IP...${NC}" +sed -i "s/external_ip: \".*\"/external_ip: \"$LOCAL_IP\"/" livekit-local.yaml + +# Configurar firewall +echo -e "${YELLOW}🔥 Configurando firewall...${NC}" +./configure-udp-ports.sh + +# Parar servicios existentes +echo -e "${YELLOW}🛑 Parando servicios existentes...${NC}" +docker-compose -f docker-compose-with-livekit.yml down 2>/dev/null || true + +# Construir imágenes +echo -e "${YELLOW}🔨 Construyendo imágenes...${NC}" +docker-compose -f docker-compose-with-livekit.yml build + +# Iniciar servicios +echo -e "${YELLOW}🚀 Iniciando servicios completos...${NC}" +docker-compose -f docker-compose-with-livekit.yml --env-file .env.local up -d + +# Esperar a que los servicios estén listos +echo -e "${YELLOW}⏳ Esperando servicios...${NC}" +sleep 15 + +# Verificar servicios +echo -e "${BLUE}🔍 Verificando servicios...${NC}" + +services=( + "redis:6379" + "livekit:7880" + "openvidu-meet:6080" + "nginx:80" +) + +for service in "${services[@]}"; do + name=$(echo $service | cut -d: -f1) + port=$(echo $service | cut -d: -f2) + + if curl -s http://localhost:$port > /dev/null 2>&1; then + echo -e "${GREEN}✅ $name funcionando en puerto $port${NC}" + else + echo -e "${RED}❌ $name no responde en puerto $port${NC}" + fi +done + +# Verificar puertos UDP +echo -e "${BLUE}📊 Verificando puertos UDP...${NC}" +if ss -tulnp | grep -q ":50000-60000"; then + echo -e "${GREEN}✅ Puertos UDP 50000-60000 abiertos${NC}" +else + echo -e "${YELLOW}⚠️ No se detectan puertos UDP - verificar manualmente${NC}" +fi + +# Mostrar URLs finales +echo -e "${GREEN}" +echo "=============================================" +echo "🎉 DESPLIEGUE COMPLETADO" +echo "=============================================" +echo "📱 OpenVidu Meet: http://$LOCAL_IP" +echo "👨‍💼 Admin Panel: http://$LOCAL_IP/admin" +echo "🔧 LiveKit API: http://$LOCAL_IP:7880" +echo "📊 Redis: $LOCAL_IP:6379" +echo "" +echo "🔐 Credenciales Admin:" +echo " Usuario: admin" +echo " Password: admin123" +echo "" +echo "⚠️ PUERTOS NECESARIOS:" +echo " TCP: 80, 6080, 6379, 7880" +echo " UDP: 50000-60000 (WebRTC)" +echo "=============================================" +echo -e "${NC}" + +# Mostrar logs en tiempo real (opcional) +read -p "¿Ver logs en tiempo real? (y/N): " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + docker-compose -f docker-compose-with-livekit.yml --env-file .env.local logs -f +fi \ No newline at end of file diff --git a/docker-compose-with-livekit.yml b/docker-compose-with-livekit.yml new file mode 100644 index 0000000..1ed50b9 --- /dev/null +++ b/docker-compose-with-livekit.yml @@ -0,0 +1,94 @@ +version: '3.8' + +services: + # OpenVidu Meet Backend + openvidu-meet: + build: . + container_name: openvidu-meet + restart: unless-stopped + environment: + NODE_ENV: production + MEET_LOG_LEVEL: info + MEET_BLOB_STORAGE_MODE: memory + PORT: 6080 + + # Admin user + MEET_INITIAL_ADMIN_USER: admin + MEET_INITIAL_ADMIN_PASSWORD: ${ADMIN_PASSWORD:-admin123} + + # CORS y proxy + SERVER_CORS_ORIGIN: "*" + TRUST_PROXY: "true" + + # LiveKit LOCAL con UDP + LIVEKIT_URL: ${LIVEKIT_URL:-ws://192.168.1.19:7880} + LIVEKIT_API_KEY: ${LIVEKIT_API_KEY:-devkey} + LIVEKIT_API_SECRET: ${LIVEKIT_API_SECRET:-secretsecretsecretsecretsecretsecret} + + ports: + - "6080:6080" + volumes: + - ./logs:/app/logs + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:6080/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + networks: + - openvidu-network + + # LiveKit Server LOCAL con puertos UDP + livekit: + image: livekit/livekit-server:latest + container_name: openvidu-livekit + restart: unless-stopped + ports: + # Puerto API/WebSocket + - "7880:7880" + # Rango UDP para WebRTC (IMPORTANTE!) + - "50000-60000:50000-60000/udp" + volumes: + - ./livekit.yaml:/livekit.yaml:ro + command: --config /livekit.yaml + networks: + - openvidu-network + depends_on: + - redis + + # Redis para LiveKit + redis: + image: redis:7-alpine + container_name: openvidu-redis + restart: unless-stopped + ports: + - "6379:6379" + command: redis-server --requirepass ${REDIS_PASSWORD:-redispassword} + volumes: + - redis_data:/data + networks: + - openvidu-network + + # Nginx Proxy + nginx-proxy: + image: nginx:alpine + container_name: openvidu-nginx + restart: unless-stopped + ports: + - "80:80" + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf:ro + - nginx-cache:/var/cache/nginx + depends_on: + - openvidu-meet + - livekit + networks: + - openvidu-network + +volumes: + nginx-cache: + redis_data: + +networks: + openvidu-network: + driver: bridge \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..06d64ef --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,70 @@ +version: '3.8' + +services: + # OpenVidu Meet Backend + openvidu-meet: + build: . + container_name: openvidu-meet + restart: unless-stopped + environment: + # Configuración básica + NODE_ENV: production + MEET_LOG_LEVEL: info + MEET_BLOB_STORAGE_MODE: memory + PORT: 6080 + + # Admin user (cambiar en producción) + MEET_INITIAL_ADMIN_USER: admin + MEET_INITIAL_ADMIN_PASSWORD: ${ADMIN_PASSWORD:-admin123} + + # CORS para proxy + SERVER_CORS_ORIGIN: "*" + + # Configuración para proxy + TRUST_PROXY: "true" + + # LiveKit (ajustar según tu setup) + LIVEKIT_URL: ${LIVEKIT_URL:-ws://localhost:7880} + LIVEKIT_API_KEY: ${LIVEKIT_API_KEY:-devkey} + LIVEKIT_API_SECRET: ${LIVEKIT_API_SECRET:-your-secret-key-32-chars-long} + + # Redis (opcional - si no se proporciona, usa memoria) + MEET_REDIS_HOST: ${REDIS_HOST:-} + MEET_REDIS_PORT: ${REDIS_PORT:-6379} + MEET_REDIS_PASSWORD: ${REDIS_PASSWORD:-} + + ports: + - "6080:6080" + volumes: + # Logs persistentes + - ./logs:/app/logs + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:6080/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + networks: + - openvidu-network + + # Nginx Proxy - Solo puerto 80 para EasyPanel + nginx-proxy: + image: nginx:alpine + container_name: openvidu-nginx + restart: unless-stopped + ports: + - "80:80" # Solo HTTP - EasyPanel maneja SSL con Traefik + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf:ro + - nginx-cache:/var/cache/nginx + depends_on: + - openvidu-meet + networks: + - openvidu-network + +volumes: + nginx-cache: + +networks: + openvidu-network: + driver: bridge \ No newline at end of file diff --git a/docs/javascript-snippets.md b/docs/javascript-snippets.md new file mode 100644 index 0000000..2400829 --- /dev/null +++ b/docs/javascript-snippets.md @@ -0,0 +1,178 @@ + +# Javascript snippets + +- `np` - nextPage +- `npssp` - nextPageServerSideProps +- `npsp` - nextPageStaticProps +- `npspth` - nextPageStaticPaths +- `nssp` - nextServerSideProps +- `nsp` - nextStaticProps +- `nspth` - nextStaticPaths +- `nip` - nextInitialProps +- `nimg` - nextImage +- `napp` - nextApp +- `ndoc` - nextDocument +- `napi` - nextApi +- `nmid` - nextMiddleware + +## `np` - nextPage + +```javascript +const FileName = ({}) => { + return
+} + +export default FileName +``` + +## `npssp` - nextPageServerSideProps + +```javascript +const FileName = ({}) => { + return
+} + +export const getServerSideProps = async (ctx) => { + return { + props: {} + } +} + +export default FileName +``` + +## `npsp` - nextPageStaticProps + +```javascript +const FileName = ({}) => { + return
+} + +export const getStaticProps = async (ctx) => { + return { + props: {}, + } +} + +export default FileName +``` + +## `npspth` - nextPageStaticPaths + +```javascript +const FileName = ({}) => { + return
+} + +export const getStaticPaths = async () => { + return { + paths: [], + fallback: false, + } +} + +export default FileName +``` + +## `nssp` - nextServerSideProps + +```javascript +export const getServerSideProps = async (ctx) => { + return { + props: {} + } +} +``` + +## `nsp` - nextStaticProps + +```javascript +export const getStaticProps = async (ctx) => { + return { + props: {}, + } +} +``` + +## `nspth` - nextStaticPaths + +```javascript +export const getStaticPaths = async () => { + return { + paths: [], + fallback: false, + } +} +``` + +## `nip` - nextInitialProps + +```javascript +FileName.getInitialProps = async (ctx) => { + return { + + } +} +``` + +## `nimg` - nextImage + +```javascript + +``` + +## `napp` - nextApp + +```javascript +export default function MyApp({ Component, pageProps }) { + return +} +``` + +## `ndoc` - nextDocument + +```javascript +import Document, { Html, Head, Main, NextScript } from 'next/document' + +class MyDocument extends Document { + static async getInitialProps(ctx) { + const initialProps = await Document.getInitialProps(ctx) + return { ...initialProps } + } + + render() { + return ( + + + +
+ + + + ); + } +} + +export default MyDocument +``` + +## `napi` - nextApi + +```javascript +export default async function handler(req, res) { + +} +``` + +## `nmid` - nextMiddleware + +```javascript +import { NextResponse } from 'next/server' +export async function middleware(request) { + +} + +export const config = { + matcher: '/about/:path*', +} +``` diff --git a/docs/typescript-snippets.md b/docs/typescript-snippets.md new file mode 100644 index 0000000..ee64afe --- /dev/null +++ b/docs/typescript-snippets.md @@ -0,0 +1,202 @@ + +# Typescript snippets + +- `np` - nextPage +- `npssp` - nextPageServerSideProps +- `npsp` - nextPageStaticProps +- `npspth` - nextPageStaticPaths +- `nssp` - nextServerSideProps +- `nsp` - nextStaticProps +- `nspth` - nextStaticPaths +- `nip` - nextInitialProps +- `nimg` - nextImage +- `napp` - nextApp +- `ndoc` - nextDocument +- `napi` - nextApi +- `nmid` - nextMiddleware + +## `np` - nextPage + +```typescript +import { NextPage } from 'next' + +interface Props {} + +const FileName: NextPage = ({}) => { + return
+} + +export default FileName +``` + +## `npssp` - nextPageServerSideProps + +```typescript +import { NextPage, GetServerSideProps } from 'next' + +interface Props {} + +const FileName: NextPage = ({}) => { + return
+} + +export const getServerSideProps: GetServerSideProps = async (ctx) => { + return { + props: {} + } +} + +export default FileName +``` + +## `npsp` - nextPageStaticProps + +```typescript +import { NextPage, GetStaticProps } from 'next' + +interface Props {} + +const FileName: NextPage = ({}) => { + return
+} + +export const getStaticProps: GetStaticProps = async (ctx) => { + return { + props: {}, + } +} + +export default FileName +``` + +## `npspth` - nextPageStaticPaths + +```typescript +import { NextPage, GetStaticPaths } from 'next' + +interface Props {} + +const FileName: NextPage = ({}) => { + return
+} + +export const getStaticPaths: GetStaticPaths = async () => { + return { + paths: [], + fallback: false, + } +} + +export default FileName +``` + +## `nssp` - nextServerSideProps + +```typescript +export const getServerSideProps: GetServerSideProps = async (ctx) => { + return { + props: {} + } +} +``` + +## `nsp` - nextStaticProps + +```typescript +export const getStaticProps: GetStaticProps = async (ctx) => { + return { + props: {}, + } +} +``` + +## `nspth` - nextStaticPaths + +```typescript +export const getStaticPaths: GetStaticPaths = async () => { + return { + paths: [], + fallback: false, + } +} +``` + +## `nip` - nextInitialProps + +```typescript +FileName.getInitialProps = async (ctx) => { + return { + + } +} +``` + +## `nimg` - nextImage + +```typescript + +``` + +## `napp` - nextApp + +```typescript +import type { AppProps } from 'next/app' + +export default function MyApp({ Component, pageProps }: AppProps) { + return +} +``` + +## `ndoc` - nextDocument + +```typescript +import Document, { Html, Head, Main, NextScript, DocumentContext } from 'next/document' + +class MyDocument extends Document { + static async getInitialProps(ctx: DocumentContext) { + const initialProps = await Document.getInitialProps(ctx) + return { ...initialProps } + } + + render() { + return ( + + + +
+ + + + ); + } +} + +export default MyDocument +``` + +## `napi` - nextApi + +```typescript +import type { NextApiRequest, NextApiResponse } from 'next' + +interface Data {} + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + +} +``` + +## `nmid` - nextMiddleware + +```typescript +import { NextResponse } from 'next/server' +import type { NextRequest } from 'next/server' + +export async function middleware(request: NextRequest) { + +} + +export const config = { + matcher: '/about/:path*', +} +``` diff --git a/fix-admin-login.sh b/fix-admin-login.sh new file mode 100755 index 0000000..12a25ed --- /dev/null +++ b/fix-admin-login.sh @@ -0,0 +1,68 @@ +#!/bin/bash +set -e + +echo "🔧 SOLUCIONANDO PROBLEMA DE LOGIN ADMIN" +echo "======================================" + +echo "1. Parando backend actual..." +pkill -f "node.*dist/src/server.js" 2>/dev/null || true +sleep 3 + +echo "2. Configurando backend con storage en memoria..." +cd /home/xesar/Documentos/openvidu-meet/meet-ce/backend + +# Crear backup del log anterior +[ -f /tmp/ovm-logs/backend.log ] && mv /tmp/ovm-logs/backend.log /tmp/ovm-logs/backend.log.backup + +echo "3. Arrancando backend con configuración correcta..." +nohup env \ + NODE_ENV=development \ + MEET_LOG_LEVEL=debug \ + MEET_BLOB_STORAGE_MODE=memory \ + MEET_INITIAL_ADMIN_USER=admin \ + MEET_INITIAL_ADMIN_PASSWORD=admin \ + LIVEKIT_URL=ws://192.168.1.19:7880 \ + LIVEKIT_URL_PRIVATE=ws://192.168.1.19:7880 \ + LIVEKIT_API_KEY=devkey \ + LIVEKIT_API_SECRET=secretsecretsecretsecretsecretsecret \ + MEET_REDIS_HOST=192.168.1.19 \ + MEET_REDIS_PORT=6379 \ + MEET_REDIS_PASSWORD=redispassword \ + node dist/src/server.js > /tmp/ovm-logs/backend.log 2>&1 & + +BACKEND_PID=$! +echo "✅ Backend iniciado con PID: $BACKEND_PID" + +echo "4. Esperando arranque (10s)..." +sleep 10 + +echo "5. Verificando estado:" +if ps -p $BACKEND_PID >/dev/null 2>&1; then + echo "✅ Proceso backend activo" +else + echo "❌ Proceso backend inactivo" + echo "Logs de error:" + tail -n 10 /tmp/ovm-logs/backend.log + exit 1 +fi + +if ss -ltn | grep -q :6080; then + echo "✅ Puerto 6080 activo" +else + echo "❌ Puerto 6080 inactivo" +fi + +echo "6. Verificando logs de admin:" +grep -i "admin\|storage.*mode\|memory" /tmp/ovm-logs/backend.log | tail -5 + +echo "" +echo "🎉 SOLUCION COMPLETADA" +echo "======================" +echo "✅ Backend corriendo con storage en memoria" +echo "✅ Usuario admin configurado: admin/admin" +echo "🌐 Accede a: http://192.168.1.19:6080" +echo "📄 Logs en: /tmp/ovm-logs/backend.log" +echo "" +echo "👤 CREDENCIALES DE LOGIN:" +echo " Usuario: admin" +echo " Contraseña: admin" \ No newline at end of file diff --git a/livekit-local.yaml b/livekit-local.yaml new file mode 100644 index 0000000..168f602 --- /dev/null +++ b/livekit-local.yaml @@ -0,0 +1,46 @@ +# LiveKit Server Configuration for LOCAL deployment with UDP +# Para usar con Docker Compose completo incluyendo LiveKit + +port: 7880 +bind_addresses: [""] + +# API Keys (mismo secret que en backend) +keys: + devkey: secretsecretsecretsecretsecretsecret + +# Redis para coordinación +redis: + address: redis:6379 + password: redispassword + db: 0 + +# Configuración RTC con UDP para red local +rtc: + # Rango de puertos UDP (DEBE coincidir con docker-compose) + port_range_start: 50000 + port_range_end: 60000 + + # IP externa para acceso desde otros dispositivos + # Cambiar por tu IP local real + use_external_ip: true + external_ip: "192.168.1.19" + + # Configuración ICE/STUN + ice_servers: + - urls: ["stun:stun.l.google.com:19302"] + +# Configuración de rooms +room: + auto_create: true + max_participants: 0 + empty_timeout: 300 + +# Egress para grabaciones (requiere Redis) +# Habilitado automáticamente con Redis + +# Logging +log_level: info +log_format: json + +# Configuración de desarrollo +development: true \ No newline at end of file diff --git a/livekit.yaml b/livekit.yaml new file mode 100644 index 0000000..b8328ed --- /dev/null +++ b/livekit.yaml @@ -0,0 +1,41 @@ +# LiveKit Server Configuration for Development +# https://docs.livekit.io/deploy/configuration/ + +port: 7880 +# Admin/API port (HTTP for rooms/egress APIs) +# The default admin port is 7880 for WebSocket and HTTP admin API +# Some builds use separate ports; adjust if needed + +# API Keys for authentication (secret must be 32+ characters) +keys: + devkey: secretsecretsecretsecretsecretsecret + +# Redis configuration (required for egress, ingress, and multi-node deployments) +redis: + address: 192.168.1.19:6379 + password: redispassword + db: 0 + +# Enable egress service (recording/streaming) +# Egress requires Redis to coordinate recording jobs +# If you see "egress not connected (redis required)", ensure Redis config is correct above + +# Development mode settings +log_level: debug + +# RTC configuration +rtc: + # Use ephemeral ports for UDP + port_range_start: 50000 + port_range_end: 60000 + # Allow connection from network (not just localhost) + use_external_ip: true + +# Room settings +room: + # Auto-create rooms when participants join + auto_create: true + # Max participants per room (0 = unlimited) + max_participants: 0 + # Empty room timeout (in seconds, 0 = no timeout) + empty_timeout: 300 diff --git a/meet-ce/backend/.env.dev b/meet-ce/backend/.env.dev index c3c05dd..8feecdb 100644 --- a/meet-ce/backend/.env.dev +++ b/meet-ce/backend/.env.dev @@ -1,4 +1,39 @@ -USE_HTTPS=false +USE_HTTPS=true MEET_LOG_LEVEL=debug SERVER_CORS_ORIGIN=* -MEET_INITIAL_API_KEY=meet-api-key \ No newline at end of file +MEET_INITIAL_API_KEY=meet-api-key + +# Admin user configuration (initial admin user created on first startup) +MEET_INITIAL_ADMIN_USER=admin +MEET_INITIAL_ADMIN_PASSWORD=admin + +# Redis configuration (used by the backend). Defaults in code point to localhost:6379. +# If you don't have a Redis server running locally, you can start one with Docker: +# docker run --name openvidu-redis -p 6379:6379 -d redis:7 +# Or with podman: +# podman run --name openvidu-redis -p 6379:6379 -d docker.io/library/redis:7 +# Environment variables read by the server (optional - only needed if you want to change defaults): +MEET_REDIS_HOST=192.168.1.19 +MEET_REDIS_PORT=6379 +MEET_REDIS_PASSWORD=redispassword +MEET_REDIS_DB=0 + +# If using Redis Sentinel, set the host list as comma separated host:port pairs and the sentinel password: +# MEET_REDIS_SENTINEL_HOST_LIST=sentinel1:26379,sentinel2:26379 +# MEET_REDIS_SENTINEL_PASSWORD=your-sentinel-password +# LiveKit URL — use the websocket URL that corresponds to the admin HTTP port. +# The livekit-server process here is listening on 7880 (client) and 7881 (admin). +# Point LIVEKIT_URL/LIVEKIT_URL_PRIVATE to the admin-enabled port so server-side +# clients (egress/room service) use the correct HTTP admin endpoint. +LIVEKIT_URL=ws://nextream.sytes.net:7880 +LIVEKIT_URL_PRIVATE=ws://nextream.sytes.net:7880 +LIVEKIT_API_KEY=devkey +LIVEKIT_API_SECRET=secretsecretsecretsecretsecretsecret + +# MinIO / S3 configuration for local development (temporarily using memory) +MEET_BLOB_STORAGE_MODE=memory +# MEET_S3_SERVICE_ENDPOINT=http://192.168.1.19:9000 +# MEET_S3_ACCESS_KEY=minioadmin +# MEET_S3_SECRET_KEY=minioadmin +# MEET_S3_BUCKET=openvidu-appdata +# MEET_S3_WITH_PATH_STYLE_ACCESS=true \ No newline at end of file diff --git a/meet-ce/frontend/angular.json b/meet-ce/frontend/angular.json index 89cf8ed..0ccdbfc 100644 --- a/meet-ce/frontend/angular.json +++ b/meet-ce/frontend/angular.json @@ -100,7 +100,9 @@ "builder": "@angular-devkit/build-angular:dev-server", "options": { "buildTarget": "openvidu-meet:build", - "proxyConfig": "src/proxy.conf.json" + "proxyConfig": "src/proxy.conf.json", + "host": "0.0.0.0", + "port": 4200 }, "configurations": { "development": { diff --git a/meet-ce/frontend/package.json b/meet-ce/frontend/package.json index 5556c84..6ffa805 100644 --- a/meet-ce/frontend/package.json +++ b/meet-ce/frontend/package.json @@ -34,7 +34,7 @@ "core-js": "3.45.1", "jwt-decode": "4.0.0", "livekit-client": "2.15.11", - "openvidu-components-angular": "workspace:*", + "openvidu-components-angular": "3.4.0", "rxjs": "7.8.2", "tslib": "2.8.1", "unique-names-generator": "4.7.1", diff --git a/meet-ce/frontend/projects/shared-meet-components/package.json b/meet-ce/frontend/projects/shared-meet-components/package.json index 93fdacb..4d41260 100644 --- a/meet-ce/frontend/projects/shared-meet-components/package.json +++ b/meet-ce/frontend/projects/shared-meet-components/package.json @@ -5,7 +5,7 @@ "module": "dist/fesm2022/openvidu-meet-shared-components.mjs", "typings": "dist/index.d.ts", "peerDependencies": { - "openvidu-components-angular": "workspace:*" + "openvidu-components-angular": "3.4.0" }, "dependencies": { "tslib": "^2.3.0" diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..664ecaf --- /dev/null +++ b/nginx.conf @@ -0,0 +1,124 @@ +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # Configuración de logs + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + error_log /var/log/nginx/error.log warn; + + # Configuración básica + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + # Compresión + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_proxied any; + gzip_comp_level 6; + gzip_types + text/plain + text/css + text/xml + text/javascript + application/json + application/javascript + application/xml+rss + application/atom+xml + image/svg+xml; + + # Rate limiting + limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; + limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s; + + # Upstream para OpenVidu Meet + upstream openvidu-backend { + server openvidu-meet:6080; + keepalive 32; + } + + # Servidor principal - Solo HTTP puerto 80 + # EasyPanel/Traefik maneja SSL y subdominios + server { + listen 80; + server_name _; + + # Headers para proxy (EasyPanel/Traefik) + 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_set_header X-Forwarded-Host $host; + + # Timeouts + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + proxy_buffering off; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # API endpoints con rate limiting + location /api/ { + limit_req zone=api burst=20 nodelay; + proxy_pass http://openvidu-backend; + } + + # Login endpoint con rate limiting estricto + location /api/auth/login { + limit_req zone=login burst=5 nodelay; + proxy_pass http://openvidu-backend; + } + + # WebSocket para LiveKit + location /ws { + proxy_pass http://openvidu-backend; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + } + + # Archivos estáticos con cache + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + proxy_pass http://openvidu-backend; + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # Todas las demás rutas + location / { + proxy_pass http://openvidu-backend; + } + + # Health check para EasyPanel + location /health { + access_log off; + return 200 "healthy\n"; + add_header Content-Type text/plain; + } + + # Security headers básicos + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + + # Ocultar versión de nginx + server_tokens off; + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7031824..8494e97 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,42 +24,6 @@ importers: specifier: 9.0.1 version: 9.0.1 - ../openvidu/openvidu-components-angular/projects/openvidu-components-angular: - dependencies: - '@angular/animations': - specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 - version: 20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)) - '@angular/cdk': - specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 - version: 20.2.9(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/common': - specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 - version: 20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/core': - specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 - version: 20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1) - '@angular/forms': - specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 - version: 20.3.4(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) - '@angular/material': - specifier: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 - version: 20.2.9(b517547b325ffc8400ae4cda6a618bfd) - '@livekit/track-processors': - specifier: ^0.6.0 - version: 0.6.1(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.15.11(@types/dom-mediacapture-record@1.0.22)) - autolinker: - specifier: ^4.0.0 - version: 4.1.5 - buffer: - specifier: ^6.0.3 - version: 6.0.3 - livekit-client: - specifier: ^2.15.0 - version: 2.15.11(@types/dom-mediacapture-record@1.0.22) - tslib: - specifier: ^2.3.0 - version: 2.8.1 - meet-ce/backend: dependencies: '@aws-sdk/client-s3': @@ -277,8 +241,8 @@ importers: specifier: 2.15.11 version: 2.15.11(@types/dom-mediacapture-record@1.0.22) openvidu-components-angular: - specifier: workspace:* - version: link:../../../openvidu/openvidu-components-angular/projects/openvidu-components-angular + specifier: 3.4.0 + version: 3.4.0(3c63e791699a7778b296d869e22cd258) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -410,8 +374,8 @@ importers: meet-ce/frontend/projects/shared-meet-components: dependencies: openvidu-components-angular: - specifier: workspace:* - version: link:../../../../../openvidu/openvidu-components-angular/projects/openvidu-components-angular + specifier: 3.4.0 + version: 3.4.0(3c63e791699a7778b296d869e22cd258) tslib: specifier: ^2.3.0 version: 2.8.1 @@ -498,365 +462,6 @@ importers: specifier: 5.9.2 version: 5.9.2 - meet-pro/backend: - dependencies: - '@aws-sdk/client-s3': - specifier: 3.846.0 - version: 3.846.0 - '@azure/storage-blob': - specifier: 12.27.0 - version: 12.27.0 - '@google-cloud/storage': - specifier: 7.17.1 - version: 7.17.1(encoding@0.1.13) - '@openvidu-meet-pro/typings': - specifier: workspace:* - version: link:../typings - '@openvidu-meet/backend': - specifier: workspace:* - version: link:../../meet-ce/backend - '@sesamecare-oss/redlock': - specifier: 1.4.0 - version: 1.4.0(ioredis@5.6.1) - archiver: - specifier: 7.0.1 - version: 7.0.1 - bcrypt: - specifier: 5.1.1 - version: 5.1.1(encoding@0.1.13) - body-parser: - specifier: 2.2.0 - version: 2.2.0 - chalk: - specifier: 5.6.2 - version: 5.6.2 - cookie-parser: - specifier: 1.4.7 - version: 1.4.7 - cors: - specifier: 2.8.5 - version: 2.8.5 - cron: - specifier: 4.3.3 - version: 4.3.3 - dotenv: - specifier: 16.6.1 - version: 16.6.1 - express: - specifier: 4.21.2 - version: 4.21.2 - express-rate-limit: - specifier: 7.5.1 - version: 7.5.1(express@4.21.2) - inversify: - specifier: 6.2.2 - version: 6.2.2(reflect-metadata@0.2.2) - ioredis: - specifier: 5.6.1 - version: 5.6.1 - jwt-decode: - specifier: 4.0.0 - version: 4.0.0 - livekit-server-sdk: - specifier: 2.13.1 - version: 2.13.1 - ms: - specifier: 2.1.3 - version: 2.1.3 - uid: - specifier: 2.0.2 - version: 2.0.2 - winston: - specifier: 3.18.3 - version: 3.18.3 - yamljs: - specifier: 0.3.0 - version: 0.3.0 - zod: - specifier: 3.25.76 - version: 3.25.76 - devDependencies: - '@types/archiver': - specifier: 6.0.3 - version: 6.0.3 - '@types/bcrypt': - specifier: 5.0.2 - version: 5.0.2 - '@types/cookie-parser': - specifier: 1.4.9 - version: 1.4.9(@types/express@4.17.23) - '@types/cors': - specifier: 2.8.19 - version: 2.8.19 - '@types/express': - specifier: 4.17.23 - version: 4.17.23 - '@types/jest': - specifier: 29.5.14 - version: 29.5.14 - '@types/ms': - specifier: 2.1.0 - version: 2.1.0 - '@types/node': - specifier: 22.16.4 - version: 22.16.4 - '@types/supertest': - specifier: 6.0.3 - version: 6.0.3 - '@types/unzipper': - specifier: 0.10.11 - version: 0.10.11 - '@types/validator': - specifier: 13.15.2 - version: 13.15.2 - '@types/yamljs': - specifier: 0.2.34 - version: 0.2.34 - '@typescript-eslint/eslint-plugin': - specifier: 6.21.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/parser': - specifier: 6.21.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.9.2) - cross-env: - specifier: 7.0.3 - version: 7.0.3 - eslint: - specifier: 8.57.1 - version: 8.57.1 - eslint-config-prettier: - specifier: 9.1.0 - version: 9.1.0(eslint@8.57.1) - jest: - specifier: 29.7.0 - version: 29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)) - jest-fetch-mock: - specifier: 3.0.3 - version: 3.0.3(encoding@0.1.13) - jest-junit: - specifier: 16.0.0 - version: 16.0.0 - nodemon: - specifier: 3.1.10 - version: 3.1.10 - openapi-generate-html: - specifier: 0.5.3 - version: 0.5.3(@types/node@22.16.4) - prettier: - specifier: 3.6.2 - version: 3.6.2 - supertest: - specifier: 7.1.3 - version: 7.1.3 - ts-jest: - specifier: 29.4.0 - version: 29.4.0(@babel/core@7.28.4)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.4))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)))(typescript@5.9.2) - ts-jest-resolver: - specifier: 2.0.1 - version: 2.0.1 - tsx: - specifier: 4.20.3 - version: 4.20.3 - typescript: - specifier: 5.9.2 - version: 5.9.2 - unzipper: - specifier: 0.12.3 - version: 0.12.3 - - meet-pro/frontend: - dependencies: - '@angular/animations': - specifier: 20.3.4 - version: 20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)) - '@angular/cdk': - specifier: 20.2.9 - version: 20.2.9(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/common': - specifier: 20.3.4 - version: 20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/compiler': - specifier: 20.3.4 - version: 20.3.4 - '@angular/core': - specifier: 20.3.4 - version: 20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1) - '@angular/forms': - specifier: 20.3.4 - version: 20.3.4(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) - '@angular/material': - specifier: 20.2.9 - version: 20.2.9(b517547b325ffc8400ae4cda6a618bfd) - '@angular/platform-browser': - specifier: 20.3.4 - version: 20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)) - '@angular/platform-browser-dynamic': - specifier: 20.3.4 - version: 20.3.4(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@20.3.4)(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))) - '@angular/router': - specifier: 20.3.4 - version: 20.3.4(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) - '@livekit/track-processors': - specifier: 0.6.1 - version: 0.6.1(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.15.11(@types/dom-mediacapture-record@1.0.22)) - '@openvidu-meet/shared-components': - specifier: workspace:* - version: link:../../meet-ce/frontend/projects/shared-meet-components - '@openvidu-meet/typings': - specifier: workspace:* - version: link:../../meet-ce/typings - autolinker: - specifier: 4.1.5 - version: 4.1.5 - core-js: - specifier: 3.45.1 - version: 3.45.1 - jwt-decode: - specifier: 4.0.0 - version: 4.0.0 - livekit-client: - specifier: 2.15.11 - version: 2.15.11(@types/dom-mediacapture-record@1.0.22) - openvidu-components-angular: - specifier: workspace:* - version: link:../../../openvidu/openvidu-components-angular/projects/openvidu-components-angular - rxjs: - specifier: 7.8.2 - version: 7.8.2 - tslib: - specifier: 2.8.1 - version: 2.8.1 - unique-names-generator: - specifier: 4.7.1 - version: 4.7.1 - zone.js: - specifier: 0.15.1 - version: 0.15.1 - devDependencies: - '@angular-builders/custom-webpack': - specifier: 20.0.0 - version: 20.0.0(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(@angular/compiler@20.3.4)(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.8)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.8)(ts-node@10.9.2(@types/node@22.18.8)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(less@4.4.2)(ng-packagr@20.3.0(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.0)(tslib@2.8.1)(tsx@4.20.3)(typescript@5.9.2) - '@angular-devkit/build-angular': - specifier: 20.3.4 - version: 20.3.4(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(@angular/compiler@20.3.4)(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.8)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.8)(ts-node@10.9.2(@types/node@22.18.8)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(ng-packagr@20.3.0(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(tsx@4.20.3)(typescript@5.9.2) - '@angular-eslint/builder': - specifier: 20.3.0 - version: 20.3.0(chokidar@4.0.3)(eslint@8.57.1)(typescript@5.9.2) - '@angular-eslint/eslint-plugin': - specifier: 20.3.0 - version: 20.3.0(@typescript-eslint/utils@8.46.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) - '@angular-eslint/eslint-plugin-template': - specifier: 20.3.0 - version: 20.3.0(@angular-eslint/template-parser@20.3.0(eslint@8.57.1)(typescript@5.9.2))(@typescript-eslint/types@8.46.1)(@typescript-eslint/utils@8.46.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) - '@angular-eslint/schematics': - specifier: 20.3.0 - version: 20.3.0(@angular-eslint/template-parser@20.3.0(eslint@8.57.1)(typescript@5.9.2))(@typescript-eslint/types@8.46.1)(@typescript-eslint/utils@8.46.1(eslint@8.57.1)(typescript@5.9.2))(chokidar@4.0.3)(eslint@8.57.1)(typescript@5.9.2) - '@angular-eslint/template-parser': - specifier: 20.3.0 - version: 20.3.0(eslint@8.57.1)(typescript@5.9.2) - '@angular/cli': - specifier: 20.3.4 - version: 20.3.4(@types/node@22.18.8)(chokidar@4.0.3) - '@angular/compiler-cli': - specifier: 20.3.4 - version: 20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2) - '@types/chai': - specifier: 4.3.20 - version: 4.3.20 - '@types/fluent-ffmpeg': - specifier: 2.1.27 - version: 2.1.27 - '@types/jasmine': - specifier: 5.1.9 - version: 5.1.9 - '@types/mocha': - specifier: 9.1.1 - version: 9.1.1 - '@types/node': - specifier: 22.18.8 - version: 22.18.8 - '@types/pixelmatch': - specifier: 5.2.6 - version: 5.2.6 - '@types/pngjs': - specifier: 6.0.5 - version: 6.0.5 - '@types/selenium-webdriver': - specifier: 4.35.1 - version: 4.35.1 - '@typescript-eslint/eslint-plugin': - specifier: 8.46.1 - version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) - '@typescript-eslint/parser': - specifier: 8.46.1 - version: 8.46.1(eslint@8.57.1)(typescript@5.9.2) - chai: - specifier: 4.5.0 - version: 4.5.0 - chromedriver: - specifier: 141.0.0 - version: 141.0.0 - cross-env: - specifier: 7.0.3 - version: 7.0.3 - eslint: - specifier: 8.57.1 - version: 8.57.1 - eslint-config-prettier: - specifier: 9.1.0 - version: 9.1.0(eslint@8.57.1) - fluent-ffmpeg: - specifier: 2.1.3 - version: 2.1.3 - jasmine-core: - specifier: 5.6.0 - version: 5.6.0 - jasmine-spec-reporter: - specifier: 7.0.0 - version: 7.0.0 - karma: - specifier: 6.4.4 - version: 6.4.4 - karma-chrome-launcher: - specifier: 3.2.0 - version: 3.2.0 - karma-coverage: - specifier: 2.2.1 - version: 2.2.1 - karma-jasmine: - specifier: 5.1.0 - version: 5.1.0(karma@6.4.4) - karma-jasmine-html-reporter: - specifier: 2.1.0 - version: 2.1.0(jasmine-core@5.6.0)(karma-jasmine@5.1.0(karma@6.4.4))(karma@6.4.4) - mocha: - specifier: 10.7.3 - version: 10.7.3 - ng-packagr: - specifier: 20.3.0 - version: 20.3.0(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2) - prettier: - specifier: 3.3.3 - version: 3.3.3 - selenium-webdriver: - specifier: 4.25.0 - version: 4.25.0 - ts-node: - specifier: 10.9.2 - version: 10.9.2(@types/node@22.18.8)(typescript@5.9.2) - typescript: - specifier: 5.9.2 - version: 5.9.2 - - meet-pro/typings: - devDependencies: - '@openvidu-meet/typings': - specifier: workspace:* - version: link:../../meet-ce/typings - typescript: - specifier: 5.9.2 - version: 5.9.2 - testapp: dependencies: '@openvidu-meet/typings': @@ -7467,6 +7072,20 @@ packages: resolution: {integrity: sha512-24epA6vxDX0hqEg+jKhMzeMZ9CvNoJlTcqat6+CL8U8bETM4Kc5i7wv2jhbqGFXHHw7kHLtPFz4QjgTooV5nHQ==} hasBin: true + openvidu-components-angular@3.4.0: + resolution: {integrity: sha512-WsJfBLBUjsnM6jDfjsOmtGlHgG1HFhIkk238f0u0VxqRdhwXlh/BK/kESxJVl6/RkhhIoU6GJ5Q3bCRXrXNzqg==} + peerDependencies: + '@angular/animations': ^17.0.0 || ^18.0.0 || ^19.0.0 + '@angular/cdk': ^17.0.0 || ^18.0.0 || ^19.0.0 + '@angular/common': ^17.0.0 || ^18.0.0 || ^19.0.0 + '@angular/core': ^17.0.0 || ^18.0.0 || ^19.0.0 + '@angular/forms': ^17.0.0 || ^18.0.0 || ^19.0.0 + '@angular/material': ^17.0.0 || ^18.0.0 || ^19.0.0 + '@livekit/track-processors': ^0.6.0 + autolinker: ^4.0.0 + buffer: ^6.0.3 + livekit-client: ^2.15.0 + opn@5.3.0: resolution: {integrity: sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==} engines: {node: '>=4'} @@ -9602,59 +9221,6 @@ snapshots: - webpack-cli - yaml - '@angular-builders/custom-webpack@20.0.0(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(@angular/compiler@20.3.4)(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.8)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.8)(ts-node@10.9.2(@types/node@22.18.8)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(less@4.4.2)(ng-packagr@20.3.0(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.0)(tslib@2.8.1)(tsx@4.20.3)(typescript@5.9.2)': - dependencies: - '@angular-builders/common': 4.0.0(@types/node@22.18.8)(chokidar@4.0.3)(typescript@5.9.2) - '@angular-devkit/architect': 0.2003.5(chokidar@4.0.3) - '@angular-devkit/build-angular': 20.3.4(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(@angular/compiler@20.3.4)(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.8)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.8)(ts-node@10.9.2(@types/node@22.18.8)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(ng-packagr@20.3.0(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(tsx@4.20.3)(typescript@5.9.2) - '@angular-devkit/core': 20.3.5(chokidar@4.0.3) - '@angular/build': 20.3.4(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(@angular/compiler@20.3.4)(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.8)(chokidar@4.0.3)(jiti@1.21.7)(karma@6.4.4)(less@4.4.2)(ng-packagr@20.3.0(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.0)(tslib@2.8.1)(tsx@4.20.3)(typescript@5.9.2) - '@angular/compiler-cli': 20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2) - lodash: 4.17.21 - webpack-merge: 6.0.1 - transitivePeerDependencies: - - '@angular/compiler' - - '@angular/core' - - '@angular/localize' - - '@angular/platform-browser' - - '@angular/platform-server' - - '@angular/service-worker' - - '@angular/ssr' - - '@rspack/core' - - '@swc/core' - - '@swc/wasm' - - '@types/node' - - '@web/test-runner' - - browser-sync - - bufferutil - - chokidar - - debug - - html-webpack-plugin - - jest - - jest-environment-jsdom - - jiti - - karma - - less - - lightningcss - - ng-packagr - - node-sass - - postcss - - protractor - - sass-embedded - - stylus - - sugarss - - supports-color - - tailwindcss - - terser - - tslib - - tsx - - typescript - - uglify-js - - utf-8-validate - - vitest - - webpack-cli - - yaml - '@angular-devkit/architect@0.2003.4(chokidar@4.0.3)': dependencies: '@angular-devkit/core': 20.3.4(chokidar@4.0.3) @@ -9673,7 +9239,7 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.4(chokidar@4.0.3) - '@angular-devkit/build-webpack': 0.2003.4(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2(esbuild@0.25.9)))(webpack@5.101.2(esbuild@0.25.9)) + '@angular-devkit/build-webpack': 0.2003.4(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2))(webpack@5.101.2) '@angular-devkit/core': 20.3.4(chokidar@4.0.3) '@angular/build': 20.3.4(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(@angular/compiler@20.3.4)(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.8)(chokidar@4.0.3)(jiti@1.21.7)(karma@6.4.4)(less@4.4.0)(ng-packagr@20.3.0(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.43.1)(tslib@2.8.1)(tsx@4.20.3)(typescript@5.9.2) '@angular/compiler-cli': 20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2) @@ -9687,13 +9253,13 @@ snapshots: '@babel/preset-env': 7.28.3(@babel/core@7.28.3) '@babel/runtime': 7.28.3 '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 20.3.4(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(typescript@5.9.2)(webpack@5.101.2(esbuild@0.25.9)) + '@ngtools/webpack': 20.3.4(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(typescript@5.9.2)(webpack@5.101.2) ansi-colors: 4.1.3 autoprefixer: 10.4.21(postcss@8.5.6) - babel-loader: 10.0.0(@babel/core@7.28.3)(webpack@5.101.2(esbuild@0.25.9)) + babel-loader: 10.0.0(@babel/core@7.28.3)(webpack@5.101.2) browserslist: 4.26.3 - copy-webpack-plugin: 13.0.1(webpack@5.101.2(esbuild@0.25.9)) - css-loader: 7.1.2(webpack@5.101.2(esbuild@0.25.9)) + copy-webpack-plugin: 13.0.1(webpack@5.101.2) + css-loader: 7.1.2(webpack@5.101.2) esbuild-wasm: 0.25.9 fast-glob: 3.3.3 http-proxy-middleware: 3.0.5 @@ -9701,32 +9267,32 @@ snapshots: jsonc-parser: 3.3.1 karma-source-map-support: 1.4.0 less: 4.4.0 - less-loader: 12.3.0(less@4.4.0)(webpack@5.101.2(esbuild@0.25.9)) - license-webpack-plugin: 4.0.2(webpack@5.101.2(esbuild@0.25.9)) + less-loader: 12.3.0(less@4.4.0)(webpack@5.101.2) + license-webpack-plugin: 4.0.2(webpack@5.101.2) loader-utils: 3.3.1 - mini-css-extract-plugin: 2.9.4(webpack@5.101.2(esbuild@0.25.9)) + mini-css-extract-plugin: 2.9.4(webpack@5.101.2) open: 10.2.0 ora: 8.2.0 picomatch: 4.0.3 piscina: 5.1.3 postcss: 8.5.6 - postcss-loader: 8.1.1(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.2(esbuild@0.25.9)) + postcss-loader: 8.1.1(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.2) resolve-url-loader: 5.0.0 rxjs: 7.8.2 sass: 1.90.0 - sass-loader: 16.0.5(sass@1.90.0)(webpack@5.101.2(esbuild@0.25.9)) + sass-loader: 16.0.5(sass@1.90.0)(webpack@5.101.2) semver: 7.7.2 - source-map-loader: 5.0.0(webpack@5.101.2(esbuild@0.25.9)) + source-map-loader: 5.0.0(webpack@5.101.2) source-map-support: 0.5.21 terser: 5.43.1 tree-kill: 1.2.2 tslib: 2.8.1 typescript: 5.9.2 webpack: 5.101.2(esbuild@0.25.9) - webpack-dev-middleware: 7.4.2(webpack@5.101.2(esbuild@0.25.9)) - webpack-dev-server: 5.2.2(webpack@5.101.2(esbuild@0.25.9)) + webpack-dev-middleware: 7.4.2(webpack@5.101.2) + webpack-dev-server: 5.2.2(webpack@5.101.2) webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(webpack@5.101.2(esbuild@0.25.9)) + webpack-subresource-integrity: 5.1.0(webpack@5.101.2) optionalDependencies: '@angular/core': 20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1) '@angular/platform-browser': 20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)) @@ -9759,12 +9325,12 @@ snapshots: - webpack-cli - yaml - '@angular-devkit/build-webpack@0.2003.4(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2(esbuild@0.25.9)))(webpack@5.101.2(esbuild@0.25.9))': + '@angular-devkit/build-webpack@0.2003.4(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2))(webpack@5.101.2)': dependencies: '@angular-devkit/architect': 0.2003.4(chokidar@4.0.3) rxjs: 7.8.2 webpack: 5.101.2(esbuild@0.25.9) - webpack-dev-server: 5.2.2(webpack@5.101.2(esbuild@0.25.9)) + webpack-dev-server: 5.2.2(webpack@5.101.2) transitivePeerDependencies: - chokidar @@ -9984,59 +9550,6 @@ snapshots: - tsx - yaml - '@angular/build@20.3.4(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(@angular/compiler@20.3.4)(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.8)(chokidar@4.0.3)(jiti@1.21.7)(karma@6.4.4)(less@4.4.2)(ng-packagr@20.3.0(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.0)(tslib@2.8.1)(tsx@4.20.3)(typescript@5.9.2)': - dependencies: - '@ampproject/remapping': 2.3.0 - '@angular-devkit/architect': 0.2003.4(chokidar@4.0.3) - '@angular/compiler': 20.3.4 - '@angular/compiler-cli': 20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2) - '@babel/core': 7.28.3 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-split-export-declaration': 7.24.7 - '@inquirer/confirm': 5.1.14(@types/node@22.18.8) - '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.5(@types/node@22.18.8)(jiti@1.21.7)(less@4.4.2)(sass@1.90.0)(terser@5.44.0)(tsx@4.20.3)) - beasties: 0.3.5 - browserslist: 4.26.3 - esbuild: 0.25.9 - https-proxy-agent: 7.0.6 - istanbul-lib-instrument: 6.0.3 - jsonc-parser: 3.3.1 - listr2: 9.0.1 - magic-string: 0.30.17 - mrmime: 2.0.1 - parse5-html-rewriting-stream: 8.0.0 - picomatch: 4.0.3 - piscina: 5.1.3 - rollup: 4.52.3 - sass: 1.90.0 - semver: 7.7.2 - source-map-support: 0.5.21 - tinyglobby: 0.2.14 - tslib: 2.8.1 - typescript: 5.9.2 - vite: 7.1.5(@types/node@22.18.8)(jiti@1.21.7)(less@4.4.2)(sass@1.90.0)(terser@5.44.0)(tsx@4.20.3) - watchpack: 2.4.4 - optionalDependencies: - '@angular/core': 20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1) - '@angular/platform-browser': 20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)) - karma: 6.4.4 - less: 4.4.2 - lmdb: 3.4.2 - ng-packagr: 20.3.0(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2) - postcss: 8.5.6 - transitivePeerDependencies: - - '@types/node' - - chokidar - - jiti - - lightningcss - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - '@angular/cdk@20.2.9(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': dependencies: '@angular/common': 20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) @@ -12526,7 +12039,7 @@ snapshots: '@napi-rs/nice-win32-x64-msvc': 1.1.1 optional: true - '@ngtools/webpack@20.3.4(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(typescript@5.9.2)(webpack@5.101.2(esbuild@0.25.9))': + '@ngtools/webpack@20.3.4(@angular/compiler-cli@20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2))(typescript@5.9.2)(webpack@5.101.2)': dependencies: '@angular/compiler-cli': 20.3.4(@angular/compiler@20.3.4)(typescript@5.9.2) typescript: 5.9.2 @@ -13851,10 +13364,6 @@ snapshots: dependencies: vite: 7.1.5(@types/node@22.18.8)(jiti@1.21.7)(less@4.4.0)(sass@1.90.0)(terser@5.44.0)(tsx@4.20.3) - '@vitejs/plugin-basic-ssl@2.1.0(vite@7.1.5(@types/node@22.18.8)(jiti@1.21.7)(less@4.4.2)(sass@1.90.0)(terser@5.44.0)(tsx@4.20.3))': - dependencies: - vite: 7.1.5(@types/node@22.18.8)(jiti@1.21.7)(less@4.4.2)(sass@1.90.0)(terser@5.44.0)(tsx@4.20.3) - '@webassemblyjs/ast@1.14.1': dependencies: '@webassemblyjs/helper-numbers': 1.13.2 @@ -14226,7 +13735,7 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@10.0.0(@babel/core@7.28.3)(webpack@5.101.2(esbuild@0.25.9)): + babel-loader@10.0.0(@babel/core@7.28.3)(webpack@5.101.2): dependencies: '@babel/core': 7.28.3 find-up: 5.0.0 @@ -14811,7 +14320,7 @@ snapshots: dependencies: is-what: 3.14.1 - copy-webpack-plugin@13.0.1(webpack@5.101.2(esbuild@0.25.9)): + copy-webpack-plugin@13.0.1(webpack@5.101.2): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 @@ -14922,7 +14431,7 @@ snapshots: dependencies: postcss: 8.5.6 - css-loader@7.1.2(webpack@5.101.2(esbuild@0.25.9)): + css-loader@7.1.2(webpack@5.101.2): dependencies: icss-utils: 5.1.0(postcss@8.5.6) postcss: 8.5.6 @@ -17471,7 +16980,7 @@ snapshots: dependencies: readable-stream: 2.3.8 - less-loader@12.3.0(less@4.4.0)(webpack@5.101.2(esbuild@0.25.9)): + less-loader@12.3.0(less@4.4.0)(webpack@5.101.2): dependencies: less: 4.4.0 optionalDependencies: @@ -17512,7 +17021,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - license-webpack-plugin@4.0.2(webpack@5.101.2(esbuild@0.25.9)): + license-webpack-plugin@4.0.2(webpack@5.101.2): dependencies: webpack-sources: 3.3.3 optionalDependencies: @@ -17766,7 +17275,7 @@ snapshots: mimic-function@5.0.1: {} - mini-css-extract-plugin@2.9.4(webpack@5.101.2(esbuild@0.25.9)): + mini-css-extract-plugin@2.9.4(webpack@5.101.2): dependencies: schema-utils: 4.3.3 tapable: 2.3.0 @@ -18171,6 +17680,20 @@ snapshots: transitivePeerDependencies: - '@types/node' + openvidu-components-angular@3.4.0(3c63e791699a7778b296d869e22cd258): + dependencies: + '@angular/animations': 20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/cdk': 20.2.9(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/common': 20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/forms': 20.3.4(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.4(@angular/animations@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.4(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.4(@angular/compiler@20.3.4)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + '@angular/material': 20.2.9(b517547b325ffc8400ae4cda6a618bfd) + '@livekit/track-processors': 0.6.1(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.15.11(@types/dom-mediacapture-record@1.0.22)) + autolinker: 4.1.5 + buffer: 6.0.3 + livekit-client: 2.15.11(@types/dom-mediacapture-record@1.0.22) + tslib: 2.8.1 + opn@5.3.0: dependencies: is-wsl: 1.1.0 @@ -18434,7 +17957,7 @@ snapshots: postcss: 8.5.6 ts-node: 10.9.2(@types/node@22.18.8)(typescript@5.7.3) - postcss-loader@8.1.1(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.2(esbuild@0.25.9)): + postcss-loader@8.1.1(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.2): dependencies: cosmiconfig: 9.0.0(typescript@5.9.2) jiti: 1.21.7 @@ -19011,7 +18534,7 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@16.0.5(sass@1.90.0)(webpack@5.101.2(esbuild@0.25.9)): + sass-loader@16.0.5(sass@1.90.0)(webpack@5.101.2): dependencies: neo-async: 2.6.2 optionalDependencies: @@ -19317,7 +18840,7 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@5.0.0(webpack@5.101.2(esbuild@0.25.9)): + source-map-loader@5.0.0(webpack@5.101.2): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 @@ -20083,23 +19606,6 @@ snapshots: terser: 5.44.0 tsx: 4.20.3 - vite@7.1.5(@types/node@22.18.8)(jiti@1.21.7)(less@4.4.2)(sass@1.90.0)(terser@5.44.0)(tsx@4.20.3): - dependencies: - esbuild: 0.25.10 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.52.3 - tinyglobby: 0.2.15 - optionalDependencies: - '@types/node': 22.18.8 - fsevents: 2.3.3 - jiti: 1.21.7 - less: 4.4.2 - sass: 1.90.0 - terser: 5.44.0 - tsx: 4.20.3 - void-elements@2.0.1: {} w3c-xmlserializer@4.0.0: @@ -20136,7 +19642,7 @@ snapshots: webidl-conversions@7.0.0: {} - webpack-dev-middleware@7.4.2(webpack@5.101.2(esbuild@0.25.9)): + webpack-dev-middleware@7.4.2(webpack@5.101.2): dependencies: colorette: 2.0.20 memfs: 4.49.0 @@ -20147,7 +19653,7 @@ snapshots: optionalDependencies: webpack: 5.101.2(esbuild@0.25.9) - webpack-dev-server@5.2.2(webpack@5.101.2(esbuild@0.25.9)): + webpack-dev-server@5.2.2(webpack@5.101.2): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -20175,7 +19681,7 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.101.2(esbuild@0.25.9)) + webpack-dev-middleware: 7.4.2(webpack@5.101.2) ws: 8.18.3 optionalDependencies: webpack: 5.101.2(esbuild@0.25.9) @@ -20193,7 +19699,7 @@ snapshots: webpack-sources@3.3.3: {} - webpack-subresource-integrity@5.1.0(webpack@5.101.2(esbuild@0.25.9)): + webpack-subresource-integrity@5.1.0(webpack@5.101.2): dependencies: typed-assert: 1.0.9 webpack: 5.101.2(esbuild@0.25.9) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f4820e8..167ef9c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,25 +1,21 @@ # ============================================================================= -# Development Workspace Configuration +# Docker/CI Workspace Configuration # ============================================================================= -# This workspace configuration is used for LOCAL DEVELOPMENT. -# It INCLUDES external packages (like openvidu-components-angular) that -# are located in sibling repositories for fast development with hot-reload. +# This workspace configuration is used for Docker builds and CI workflows. +# It EXCLUDES external packages (like openvidu-components-angular) that +# are not part of this repository. # -# For Docker builds and CI, use pnpm-workspace.docker.yaml instead. +# For local development, use pnpm-workspace.yaml instead. # # See docs/ci-docker-dependencies-strategy.md for more information. # ============================================================================= packages: - - ../openvidu/openvidu-components-angular/projects/openvidu-components-angular - meet-ce/typings - meet-ce/frontend - meet-ce/frontend/webcomponent - meet-ce/frontend/projects/shared-meet-components - meet-ce/backend - - meet-pro/frontend - - meet-pro/backend - - meet-pro/typings - testapp ignoredBuiltDependencies: diff --git a/restart-stack.sh b/restart-stack.sh new file mode 100755 index 0000000..577856c --- /dev/null +++ b/restart-stack.sh @@ -0,0 +1,63 @@ +#!/bin/bash +set -e + +echo "🔄 REINICIANDO STACK COMPLETO OPENVIDU MEET" +echo "==========================================" + +# Crear directorio de logs +mkdir -p /tmp/ovm-logs + +echo -e "\n1️⃣ Matando procesos existentes..." +pkill -f "node.*dist/src/server.js" || true +pkill -f "livekit-server" || true +pkill -f "ng serve" || true +pkill -f "pnpm.*start" || true +sleep 3 + +echo -e "\n2️⃣ Reiniciando Backend..." +cd /home/xesar/Documentos/openvidu-meet/meet-ce/backend +pnpm run build +nohup env \ + NODE_ENV=development \ + LIVEKIT_URL=wss://livekit-server.bfzqqk.easypanel.host \ + LIVEKIT_URL_PRIVATE=wss://livekit-server.bfzqqk.easypanel.host \ + LIVEKIT_API_KEY=devkey \ + LIVEKIT_API_SECRET=secretsecretsecretsecretsecretsecret \ + MEET_REDIS_HOST=192.168.1.19 \ + MEET_REDIS_PORT=6379 \ + MEET_REDIS_PASSWORD=redispassword \ + MEET_BLOB_STORAGE_MODE=s3 \ + MEET_S3_SERVICE_ENDPOINT=http://192.168.1.19:9000 \ + MEET_S3_ACCESS_KEY=minioadmin \ + MEET_S3_SECRET_KEY=minioadmin \ + MEET_S3_BUCKET=openvidu-appdata \ + MEET_S3_WITH_PATH_STYLE_ACCESS=true \ + MEET_INITIAL_ADMIN_USER=admin \ + MEET_INITIAL_ADMIN_PASSWORD=admin \ + node dist/src/server.js > /tmp/ovm-logs/backend.log 2>&1 & + +echo "✅ Backend iniciado" + +echo -e "\n3️⃣ Reiniciando LiveKit..." +cd /home/xesar/Documentos/openvidu-meet +nohup livekit-server --config livekit.yaml > /tmp/ovm-logs/livekit.log 2>&1 & +echo "✅ LiveKit iniciado" + + +echo -e "\n⏳ Esperando arranque de servicios (15s)..." +sleep 15 + +echo -e "\n🔍 Verificación final:" +echo "Puertos activos:" +ss -ltn | egrep '6080|7880|6379|9000' | sort + +echo -e "\nTest conectividad:" +curl -s -o /dev/null -w "✅ Backend (6080): %{http_code}\n" https://openvidu.bfzqqk.easypanel.host || echo "❌ Backend no responde" +redis-cli -h 192.168.1.19 -p 6379 -a redispassword ping 2>/dev/null && echo "✅ Redis: PONG" || echo "❌ Redis no responde" + +echo -e "\n🚀 STACK REINICIADO COMPLETAMENTE" +echo "📄 Logs en: /tmp/ovm-logs/" +echo -e "\n🌐 URLs:" +echo " • Frontend: http://192.168.1.19:4200" +echo " • Backend: https://openvidu.bfzqqk.easypanel.host" +echo " • LiveKit: wss://livekit-server.bfzqqk.easypanel.host" \ No newline at end of file diff --git a/setup-livekit-ssl.sh b/setup-livekit-ssl.sh new file mode 100755 index 0000000..9593415 --- /dev/null +++ b/setup-livekit-ssl.sh @@ -0,0 +1,96 @@ +#!/bin/bash +set -e + +echo "🔒 CONFIGURACIÓN SSL PARA LIVEKIT CON DOMINIO" +echo "==============================================" + +DOMAIN="nextream.sytes.net" +EMAIL="tu-email@dominio.com" # Cambia por tu email + +echo "📋 Configuración:" +echo " • Dominio: $DOMAIN" +echo " • Email: $EMAIL" +echo " • Puerto HTTPS: 443" +echo " • Puerto LiveKit: 7880" + +# Instalar certbot si no existe +if ! command -v certbot &> /dev/null; then + echo "📦 Instalando Certbot..." + sudo apt update + sudo apt install -y certbot python3-certbot-nginx +fi + +# Generar certificado SSL +echo "🔐 Generando certificado SSL..." +sudo certbot certonly --standalone \ + --email $EMAIL \ + --agree-tos \ + --no-eff-email \ + -d $DOMAIN + +# Crear configuración Nginx para LiveKit +echo "⚙️ Configurando Nginx para LiveKit..." +sudo tee /etc/nginx/sites-available/livekit-ssl > /dev/null </dev/null || true +sleep 2 + +# 2. Limpiar Redis +echo "2. Limpiando datos conflictivos en Redis..." +redis-cli -h 192.168.1.19 -p 6379 -a redispassword FLUSHDB 2>/dev/null || echo "Redis no disponible, usando modo local" + +# 3. Arrancar backend limpio +echo "3. Arrancando backend limpio..." +cd /home/xesar/Documentos/openvidu-meet/meet-ce/backend + +env \ + NODE_ENV=development \ + MEET_LOG_LEVEL=debug \ + MEET_BLOB_STORAGE_MODE=memory \ + MEET_INITIAL_ADMIN_USER=admin \ + MEET_INITIAL_ADMIN_PASSWORD=admin \ + node dist/src/server.js > /tmp/ovm-logs/backend-final.log 2>&1 & + +BACKEND_PID=$! +echo "✅ Backend iniciado con PID: $BACKEND_PID" + +# 4. Esperar y verificar +echo "4. Esperando arranque (15s)..." +sleep 15 + +# 5. Verificar estado +if ps -p $BACKEND_PID >/dev/null 2>&1; then + echo "✅ Proceso backend activo" + + if ss -ltn | grep -q :6080; then + echo "✅ Puerto 6080 escuchando" + + # Test de conectividad + if curl -s -f http://localhost:6080/ >/dev/null 2>&1; then + echo "✅ Backend responde correctamente" + echo "" + echo "🎉 SOLUCION COMPLETADA" + echo "=====================" + echo "🌐 URL: http://localhost:6080" + echo "👤 Usuario: admin" + echo "🔑 Contraseña: admin" + echo "" + echo "Si aún no puedes acceder, revisa:" + echo "• Firewall local" + echo "• Antivirus" + echo "• Proxy del navegador" + else + echo "❌ Backend no responde - revisar logs" + tail -n 10 /tmp/ovm-logs/backend-final.log + fi + else + echo "❌ Puerto 6080 no está escuchando" + tail -n 10 /tmp/ovm-logs/backend-final.log + fi +else + echo "❌ Proceso backend no está activo" + echo "Logs de error:" + cat /tmp/ovm-logs/backend-final.log +fi \ No newline at end of file