Tutorial

Autoalojamiento

Alojar Jitsi en su propio VPS

Jitsi Meet es una solución de videoconferencia de código abierto que funciona directamente en el navegador, sin instalación del lado del participante. Autoalojarlo en un VPS le da salas sin límite, sin límite de duración ni recopilación de datos. El despliegue es rápido — la configuración del servidor TURN (coturn), en cambio, es lo que hace fracasar la mayoría de las instalaciones: sin él, el video funciona en la red local pero se detiene en cuanto un participante está detrás de un NAT corporativo o de un operador con CGN. Esta guía cubre la instalación completa, la configuración avanzada de coturn, el monitoreo del puente de video y la solución de los errores más frecuentes.

11 min de lectura6 pasos
Contenido· Jitsi autoalojado vs Zoom: lo que cambia de verdad1/9
  1. 01Jitsi autoalojado vs Zoom: lo que cambia de verdad
  2. 02Beneficios concretos de un Jitsi autoalojado
  3. 03Requisitos previos con cifras antes de empezar
  4. 04Despliegue paso a paso: Docker, .env, coturn y primera prueba
  5. 05Configuración avanzada: grabación, autenticación y límites
  6. 06Endurecimiento: fail2ban en el servicio TURN
  7. 07Solución de problemas: los cuatro errores más frecuentes
  8. 08Monitoreo: vigilar el ancho de banda y los participantes
  9. 09Su Jitsi está en marcha — gestione el ancho de banda

Jitsi autoalojado vs Zoom: lo que cambia de verdad

Los servicios de videoconferencia de consumo (Zoom, Google Meet, Teams) imponen límites de duración en los planes gratuitos, cuotas de participantes, y conservan sus grabaciones en sus propios servidores. Jitsi Meet, autoalojado, elimina estas restricciones: salas sin límite, duración sin límite, ninguna cuenta requerida para unirse a una reunión, flujos de video que permanecen en su infraestructura. Es especialmente pertinente para una organización preocupada por la confidencialidad de sus reuniones, para un despacho que trata datos sensibles, o para integrar la videoconferencia en una aplicación de terceros (Jitsi ofrece una API iframe estable). El coste de funcionamiento se reduce a la factura del VPS — ninguna suscripción por puesto, ningún sobrecoste de software.

Beneficios concretos de un Jitsi autoalojado

  • Reuniones sin límite de duración ni de número de salas — ningún temporizador que corte la reunión.
  • Ninguna cuenta requerida para los participantes: basta un enlace para unirse.
  • API iframe para integrar la videoconferencia directamente en su aplicación o en su sitio web.
  • Cifrado del transporte (DTLS-SRTP) y control total sobre las eventuales grabaciones.
  • Personalización completa de la interfaz: logotipo, colores, nombre de dominio de las salas.
  • Ninguna telemetría enviada a terceros — los flujos de video no salen de su VPS.

Requisitos previos con cifras antes de empezar

Jitsi se dimensiona por el ancho de banda, no por la CPU. La documentación de Jitsi recomienda 8 GB de RAM (4 GB bastan para reuniones pequeñas), unos 4 núcleos dedicados para un servidor básico y, sobre todo, un enlace de red fiable: un flujo 720p consume unos 2,5 Mbit/s, y un enlace de 100 Mbit/s no sostiene a una veintena de participantes en alta definición. Vigile la carga de red del JVB. Tres puertos deben ser accesibles desde internet: TCP 443 (HTTPS), TCP 80 (desafío de Let's Encrypt y redirección a HTTPS), UDP 10000 (medios JVB). El puerto TCP 4443, citado por guías antiguas, ya no figura en la lista oficial. Si coturn se ejecuta en el mismo VPS, añada sus puertos: 3478 en UDP y TCP, 5349 en TLS (el 443 ya lo ocupa el contenedor web). Se necesita Docker con Compose V2 (comando docker compose), un nombre de dominio meet.sudominio.com con un registro A que apunte a la IP pública del VPS, y una IP pública dedicada y estable — una IP compartida complica seriamente la configuración de coturn.

Despliegue paso a paso: Docker, .env, coturn y primera prueba

  1. Obtener docker-jitsi-meet

    Descargue la última release desde la página de releases de github.com/jitsi/docker-jitsi-meet y descomprímala: la guía oficial desaconseja clonar el repositorio, cuya rama principal usa las imágenes unstable. Cree las carpetas de configuración que indica la guía (~/.jitsi-meet-cfg/…, incluidas storage y tmp, con escritura para el uid 1000): los contenedores se ejecutan sin root y, si no, se niegan a arrancar. Copie env.example a .env, luego ejecute ./gen-passwords.sh — este script genera todos los secretos internos (Prosody, Jicofo, JVB). No se salte este paso: los valores por defecto no son secretos. La release stable-11248-3 (noviembre 2026) es la última estable; evite master y las imágenes unstable en producción — los componentes internos cambian sin previo aviso.

  2. Configurar PUBLIC_URL, los puertos y JVB_ADVERTISE_IPS

    En .env, fije primero HTTP_PORT=80 y HTTPS_PORT=443 (8000 y 8443 por defecto). Después, dos variables son críticas: PUBLIC_URL=https://meet.sudominio.com (utilizada por el cliente web para construir las URL de las salas) y JVB_ADVERTISE_IPS=<IP_PUBLICA_DEL_VPS> (la dirección que el JVB anuncia a los clientes para establecer la conexión de medios directa; sustituye a la antigua DOCKER_HOST_ADDRESS). Sin JVB_ADVERTISE_IPS, el JVB intenta descubrir su IP pública por STUN; si la dirección anunciada es errónea, las llamadas fallan en cuanto se unen más de dos participantes.

  3. Activar Let's Encrypt en .env

    Añada en .env: ENABLE_LETSENCRYPT=1, LETSENCRYPT_DOMAIN=meet.sudominio.com, [email protected]. Compruebe que el puerto 80 está realmente abierto antes de arrancar — Let's Encrypt utiliza un desafío HTTP-01 que requiere una respuesta en ese puerto. El contenedor web obtiene y renueva el certificado con acme.sh (servicio de renovación interno) y lo guarda en ~/.jitsi-meet-cfg/storage/web: conserve esa carpeta entre reinicios. Añada también LETSENCRYPT_ACME_SERVER=letsencrypt: sin ella, acme.sh usa ZeroSSL por defecto.

  4. Configurar coturn (servidor TURN)

    Es la etapa que la mayoría de las guías pasan por alto y la que hace fracasar la instalación. docker-jitsi-meet no incluye coturn: instálelo aparte (paquete o contenedor) y declárelo en .env para que Prosody entregue a los clientes credenciales temporales: TURNS_HOST=turn.sudominio.com y TURNS_PORT para TLS, y además TURN_HOST=turn.sudominio.com, TURN_PORT=3478 y TURN_TRANSPORT=udp,tcp. El puerto 443 en TLS permite atravesar los cortafuegos más restrictivos, que bloquean los puertos no estándar pero dejan pasar todo lo que se parece a HTTPS; exige una IP que el contenedor web no ocupe ya, si no, mantenga 5349.

    Genere después un secreto compartido (openssl rand -hex 32) y colóquelo en TURN_CREDENTIALS en .env y en coturn (use-auth-secret y static-auth-secret=<el mismo secreto>); nunca no-auth, que convertiría su servidor en un relé abierto a cualquiera. El certificado TLS se declara en la configuración de coturn (cert= y pkey=), no en .env. Si coturn se ejecuta en un contenedor separado, monte estos archivos como volumen.

    Último punto que a menudo se olvida: coturn no bloquea por defecto los rangos RFC1918 (192.168.x.x, 10.x.x.x, 172.16.x.x): solo rechaza el loopback. Un cliente autenticado puede, por tanto, retransmitir tráfico hacia su red interna. Añada no-multicast-peers y líneas denied-peer-ip para esos rangos y, si el JVB tiene una dirección interna, autorice solo esa con allowed-peer-ip.

  5. Arrancar la stack y comprobar el JVB

    Ejecute docker compose up -d. Espere 30 segundos, luego: docker compose logs jvb 2>&1 | grep -E 'register|connected|error'. Debe ver una línea que indique que el JVB se ha registrado en Jicofo. Si ve Failed to register o Connection refused, Prosody aún no está listo — vuelva a lanzarlo al cabo de un minuto. Compruebe después que los puertos responden: nc -zv meet.sudominio.com 443 (web, TCP), nc -zv turn.sudominio.com 3478 (coturn, TCP) y nc -zvu meet.sudominio.com 10000 (JVB, UDP; un éxito en UDP solo es orientativo).

  6. Primera prueba de video desde dos redes diferentes

    Abra https://meet.sudominio.com desde su equipo habitual y desde un segundo dispositivo en una red diferente (un teléfono con datos móviles, por ejemplo). Si ambos participantes se ven y se oyen, el TURN funciona. Una prueba desde dos equipos en la misma red local no valida coturn — tiene éxito en modo punto a punto sin solicitar nunca el relé.

Configuración avanzada: grabación, autenticación y límites

Grabación de las reuniones. Jitsi integra Jibri para la grabación local o el streaming RTMP. Jibri captura el renderizado de un navegador en tiempo real: una instancia solo graba una reunión a la vez, y la documentación de Jitsi pide al menos 8 GB de RAM por instancia en 720p, preferiblemente en un servidor separado. Active ENABLE_RECORDING=1 en .env y arranque el contenedor Jibri incluido: docker compose -f docker-compose.yml -f jibri.yml up -d. Autenticación de los organizadores. Por defecto, cualquiera puede crear una sala: una instancia pública así configurada se convierte en videoconferencia gratuita para desconocidos, con su ancho de banda. Active ENABLE_AUTH=1, AUTH_TYPE=internal y ENABLE_GUESTS=1 para exigir una cuenta del lado del organizador dejando que los invitados se unan libremente. Cree las cuentas de anfitrión con docker compose exec prosody prosodyctl --config /run/prosody/config/prosody.cfg.lua register admin meet.jitsi <contrasena>: meet.jitsi es el dominio XMPP interno, no su nombre público, y la contraseña se genera (openssl rand -base64 18) en lugar de reutilizarse. Limitar los participantes anónimos. ENABLE_LOBBY=1 habilita la sala de espera: una vez que el moderador la activa, cada entrada debe validarse antes de acceder a la sala. Combinado con ENABLE_AUTH=1, esto da un control completo sobre quién accede a qué.

Endurecimiento: fail2ban en el servicio TURN

coturn expone un servicio accesible desde internet. Instale fail2ban y cree un filtro sobre los intentos de autenticación TURN fallidos: los fallos aparecen en el registro de coturn con un código 401; compruebe el formato exacto de su versión antes de escribir la regex del filtro. Una jail de fail2ban con maxretry=10 y bantime=600 basta para desalentar los escaneos automáticos sin afectar a sus usuarios legítimos. Fije el registro con log-file=/var/log/turnserver.log en la configuración de coturn (sin esta opción, coturn elige por sí mismo un archivo en /var/log, /var/tmp o /tmp), haga que fail2ban vigile esa ruta, o monte ese archivo desde el contenedor.

Solución de problemas: los cuatro errores más frecuentes

Sin sonido o video bloqueado en «connecting» — coturn + UDP 10000. Es la avería más frecuente. Compruebe en este orden: (1) ufw status — ¿están abiertos los puertos TCP 443 y UDP 10000? (2) los registros de coturn (journalctl -u coturn en nativo, docker logs <contenedor-coturn> si no) — ¿arranca coturn sin error de certificado? (3) Desde una máquina externa: curl -v telnet://meet.sudominio.com:3478 — ¿responde coturn? (4) En los logs del navegador (F12 → Consola): ¿ve ICE failed o failed to gather candidates? Si es así, coturn no es accesible desde el exterior. Compruebe que TURN_HOST y TURNS_HOST en .env resuelven a la IP real del servidor coturn. Conexión rechazada en TCP 443. Si el certificado Let's Encrypt no pudo emitirse (puerto 80 cerrado en el primer arranque), el contenedor web se detiene tras el mensaje Failed to obtain a certificate from the Let's Encrypt CA y ya nada responde en el 443. Solución: abra el puerto 80, compruebe HTTP_PORT=80 y vuelva a lanzar docker compose up -d; no hace falta borrar la configuración, y cada nuevo intento cuenta en los límites de Let's Encrypt. Compartir pantalla rechazado por el navegador. Compartir la pantalla exige un contexto seguro (HTTPS válido). Si ve getUserMedia is not supported, el certificado no es válido o el dominio no está en HTTPS. Compruebe PUBLIC_URL — debe empezar por https:// con un dominio cuyo certificado sea válido, no una IP en bruto. Error «ICE failed» persistente pese a un coturn operativo. Compruebe la variable JVB_ADVERTISE_IPS (antes DOCKER_HOST_ADDRESS): debe contener la IP pública del VPS, no la IP interna del contenedor Docker (172.17.x.x). Si su VPS está detrás de un NAT cloud (raro pero existente), necesita la IP NAT externa, no la IP de la interfaz de red.

Monitoreo: vigilar el ancho de banda y los participantes

El puente de video JVB expone una API de estadísticas en tiempo real en http://localhost:8080/colibri/stats. Este endpoint JSON informa del número de conferencias activas, participantes, ancho de banda entrante y saliente en kbit/s, y el RTT medio (rtt_aggregate). El puerto 8080 solo se publica en 127.0.0.1: manténgalo así. Para una vigilancia continua, el JVB ya expone sus métricas en formato Prometheus en /metrics (mismo puerto privado); del lado de Prosody, active PROSODY_ENABLE_METRICS=1 en .env. Conecte después una pila Prometheus + Grafana: el repositorio incluye prometheus.yml y grafana.yml, que publican los puertos 9090 y 3000 en todas las interfaces. Limítelos a 127.0.0.1 o a una VPN, porque los puertos publicados por Docker eluden las reglas de ufw.

Sin Prometheus, una vigilancia mínima se logra con un cron que consulta /colibri/stats y alerta cuando el rendimiento supera un umbral: curl -s http://127.0.0.1:8080/colibri/stats | python3 -c "import json,sys; s=json.load(sys.stdin); print(s.get('bit_rate_download',0), s.get('bit_rate_upload',0))".

Para estimar la capacidad antes de la saturación: la capacidad de un JVB depende ante todo del enlace de red y de las resoluciones enviadas; mídala con su propia carga en lugar de fiarse de una cifra genérica. Cuando el límite se acerca, rtt_aggregate sube y la calidad percibida cae antes de que la CPU sature — esa es la señal para añadir otra instancia JVB.

Su Jitsi está en marcha — gestione el ancho de banda

Jitsi funciona en modo SFU: el puente de video (JVB) retransmite cada flujo hacia cada participante, por lo que el ancho de banda saliente crece proporcionalmente al número de participantes multiplicado por el número de flujos. Un flujo 720p pesa unos 2,5 Mbit/s según la documentación de Jitsi: multiplique por el número de flujos realmente enviados a cada participante para estimar el caudal saliente. Fije channelLastN: 5 en custom-config.js (carpeta web de la configuración) para recibir solo los N últimos videos activos para limitar los flujos del lado del cliente en las reuniones grandes, y vigile docker stats jvb para anticipar la saturación. Por encima de una veintena de participantes simultáneos regulares, despliegue varias instancias JVB en VPS distintos detrás de un único Jicofo: es la arquitectura de escalado horizontal nativa de Jitsi. Para despliegues multi-organización o multidominio, tenga en cuenta que una instalación docker-jitsi-meet solo tiene una PUBLIC_URL: si cada organización necesita sus propias cuentas y un espacio de salas aislado, prevea una instancia por organización, en su propio subdominio.

Lance su servidor Jitsi en un VPS Cloud ServOrbit

Un VPS Cloud con IP pública dedicada, ancho de banda generoso y acceso root le permite desplegar Jitsi Meet, coturn y Jibri sin límite de reuniones. Sus videoconferencias permanecen en su infraestructura.