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 +