Tutoriales de VPS
Instalar Jitsi Meet en un VPS (2026): Docker, HTTPS, 10000 UDP, autenticación, TURN y grabación
Configura un sistema de videoconferencia en un VPS Ubuntu con la versión estable oficial docker-jitsi-meet, cubriendo la elección de configuración, HTTPS del dominio, 10000 UDP, autenticación de salas, TURN, planificación de grabación, copias de seguridad y actualizaciones, y solución de problemas de audio y vídeo.

Jitsi Meet es un sistema de videoconferencia de código abierto adecuado para reuniones de equipo, enseñanza en línea, entrevistas remotas y comunicación con clientes. No exige que los participantes instalen un sistema de cuentas: basta con abrir un enlace en el navegador para entrar en la reunión, y también se puede usar la autenticación para limitar la creación de salas solo a miembros internos.
Este artículo despliega Jitsi Meet en un VPS Ubuntu usando la versión estable oficial docker-jitsi-meet, cubriendo la configuración del servidor, HTTPS del dominio, el puerto de medios 10000/UDP, autenticación de salas, TURN, copias de seguridad, actualizaciones y solución de problemas comunes. A fecha del 1 de septiembre de 2026, la última versión estable oficial es stable-11146-2.
| Escenario | Adecuado | Notas |
|---|---|---|
| Reuniones internas de equipos pequeños | Adecuado | Se puede limitar la creación de salas solo a usuarios autenticados |
| Cursos en línea, difusión pública | Adecuado | Admite sala de espera, levantar la mano, chat y compartir pantalla |
| Comunicación remota con clientes | Adecuado | Se une con un dominio, sin instalación obligatoria de cliente |
| Transmisión en directo a gran escala | No debe usarse una sola instancia de Jitsi | Requiere Jibri, una CDN o una plataforma de streaming dedicada |
| Grabación con cumplimiento estricto y archivo a largo plazo | Requiere diseño adicional | La grabación, el almacenamiento, los permisos y las políticas de retención deben planificarse por separado |
Los flujos de vídeo de Jitsi son reenviados principalmente por Jitsi Videobridge. No es una aplicación web común: la CPU y la memoria importan, pero el ancho de banda público, la pérdida de paquetes, el jitter, la accesibilidad UDP y las regiones donde se encuentran los participantes suelen afectar más directamente a la experiencia.
Las siguientes configuraciones son puntos de partida conservadores, no garantías fijas de concurrencia. Activar HD, compartir pantalla, grabación o muchas cámaras aumentará notablemente los requisitos de recursos.
| Uso | Configuración recomendada | Notas |
|---|---|---|
| Pruebas y reuniones de 2-4 personas | 2 núcleos, 2GB, 30GB SSD | Adecuado para validar funciones, no recomendado para carga máxima sostenida |
| Reuniones diarias de equipos pequeños | 4 núcleos, 8GB, 50GB+ NVMe | Deja margen para JVB, Jicofo, Prosody y Docker |
| Varias reuniones simultáneas | 8 núcleos, 16GB o más | Requiere pruebas de carga del ancho de banda de subida, pérdida de paquetes y latencia regional |
| Grabación o transmisión en directo | Planificar Jibri por separado | El renderizado del navegador, la codificación y la escritura de archivos consumen bastantes recursos |
Prioriza:
- VPS con velocidad de puerto de 1Gbps o superior y tráfico mensual suficiente;
- Centros de datos cercanos a los principales participantes;
- IPv4 pública, capacidad de abrir UDP, reglas de grupo de seguridad claras;
- Rendimiento de CPU estable, sin sobreventa grave;
- Soporte de instantáneas y rescate por consola.
Si aún dudas entre 2 núcleos/2GB y 4 núcleos/8GB, puedes consultar Cómo elegir la configuración de un VPS. Para videoconferencia conviene priorizar la calidad de red y el margen de memoria, no solo el tamaño del disco.
Prepara lo siguiente:
- Un VPS Ubuntu 24.04 LTS nuevo;
- Acceso SSH como root o con sudo;
- Un dominio, por ejemplo
meet.example.com; - Una dirección de correo que pueda recibir notificaciones de certificados;
- Las regiones principales de los usuarios de las reuniones y una estimación básica de concurrencia.
Añade un registro DNS A:
meet.example.com A 203.0.113.10
Confirma el dominio y la IP pública:
dig +short meet.example.com A
curl -4 ifconfig.me
Ambos resultados deben coincidir. Si el VPS aún no tiene IPv6 configurado, no añadas un registro AAAA que apunte a una dirección incorrecta.
La documentación oficial de Jitsi Docker requiere abrir:
| Puerto | Protocolo | Uso |
|---|---|---|
| 22 | TCP | Administración SSH |
| 80 | TCP | Redirección HTTP y validación de certificados |
| 443 | TCP | HTTPS, WebSocket y acceso web |
| 10000 | UDP | Medios de audio y vídeo de Jitsi Videobridge |
Al usar UFW, permite primero SSH y luego habilita el cortafuegos:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 10000/udp
sudo ufw enable
sudo ufw status numbered
También debes configurar las mismas reglas en el grupo de seguridad del proveedor de nube. Cambiar solo UFW o solo el grupo de seguridad no es suficiente. Antes de hacerlo, puedes leer Cómo recuperarse de la pérdida de SSH causada por UFW para no quedarte fuera de la sesión SSH actual.
10000/UDP es el puerto que más fácilmente se pasa por alto. Si la página web abre pero las reuniones de varias personas no tienen sonido, se congelan o se desconectan tras unos segundos, revísalo primero.
Actualiza el sistema e instala Docker, Compose y herramientas de descompresión:
sudo apt update
sudo apt upgrade -y
sudo apt install -y docker.io docker-compose-v2 unzip curl ca-certificates
sudo systemctl enable --now docker
sudo docker version
sudo docker compose version
Si el repositorio del sistema no tiene docker-compose-v2, instala el Compose Plugin desde el repositorio oficial de Docker en lugar de recurrir al Python docker-compose v1, sin mantenimiento desde hace años.
No clones master directamente para producción. La documentación oficial indica que master con imágenes unstable diarias es para desarrollo, y que los despliegues en producción deben descargar un Release.
Este artículo fija stable-11146-2:
cd /opt
sudo curl -fL https://github.com/jitsi/docker-jitsi-meet/archive/refs/tags/stable-11146-2.zip -o jitsi.zip
sudo unzip jitsi.zip
sudo mv docker-jitsi-meet-stable-11146-2 jitsi-meet
sudo chown -R "$USER":"$USER" /opt/jitsi-meet
cd /opt/jitsi-meet
cp env.example .env
A partir de esta versión, los contenedores se ejecutan como no root con un sistema de archivos de solo lectura. La estructura de configuración, datos persistentes y directorios de ejecución difiere de las versiones antiguas, por lo que actualizar una instancia antigua no puede hacerse simplemente cambiando la etiqueta de la imagen.
Genera las contraseñas XMPP internas para Jicofo, JVB, Jigasi y Jibri:
cd /opt/jitsi-meet
./gen-passwords.sh
El script modifica .env y conserva .env.bak. Estas contraseñas se usan para la comunicación entre componentes; no deben dejarse vacías ni reutilizar manualmente la misma contraseña.
Crea los directorios requeridos por stable-11146 y versiones posteriores:
sudo mkdir -p /opt/jitsi-meet-cfg/{web,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri,transcriber}
sudo mkdir -p /opt/jitsi-meet-cfg/storage/{jibri,prosody,transcripts,web}
sudo mkdir -p /opt/jitsi-meet-cfg/tmp/{web-crontabs,web-load-test}
sudo chmod 777 /opt/jitsi-meet-cfg/storage/{jibri,prosody,transcripts,web}
sudo chmod 777 /opt/jitsi-meet-cfg/tmp/{web-crontabs,web-load-test}
Los contenedores oficiales actuales se ejecutan como usuario sin privilegios con UID/GID 1000, y los directorios storage y tmp que deben escribirse tienen que ser escribibles. Si faltan directorios o los permisos son incorrectos, el contenedor se negará a arrancar.
Edita .env:
nano /opt/jitsi-meet/.env
Como mínimo modifica o añade:
CONFIG=/opt/jitsi-meet-cfg
HTTP_PORT=80
HTTPS_PORT=443
TZ=Asia/Shanghai
PUBLIC_URL=https://meet.example.com
JVB_ADVERTISE_IPS=203.0.113.10
ENABLE_LETSENCRYPT=1
LETSENCRYPT_DOMAIN=meet.example.com
[email protected]
LETSENCRYPT_ACME_SERVER=letsencrypt
ENABLE_HTTP_REDIRECT=1
ENABLE_PREJOIN_PAGE=1
ENABLE_LOBBY=1
ENABLE_REQUIRE_DISPLAY_NAME=1
RESTART_POLICY=unless-stopped
JVB_ADVERTISE_IPS debe contener la IP pública a la que los clientes realmente pueden acceder. Si el VPS está detrás de NAT, tiene varias interfaces de red o ha migrado de IP, un valor incorrecto aquí hará que la señalización funcione pero los medios fallen.
No elimines las líneas de contraseña generadas por gen-passwords.sh. Tras guardar, comprueba primero las variables clave:
cd /opt/jitsi-meet
grep -E '^(CONFIG|PUBLIC_URL|JVB_ADVERTISE_IPS|HTTP_PORT|HTTPS_PORT|ENABLE_LETSENCRYPT|LETSENCRYPT_DOMAIN)=' .env
No publiques la salida completa de .env en tickets, capturas o repositorios públicos, porque contiene contraseñas internas.
Descarga las imágenes e inicia:
cd /opt/jitsi-meet
sudo docker compose pull
sudo docker compose up -d
sudo docker compose ps
Observa los registros del primer arranque:
sudo docker compose logs -f --tail=100 web prosody jicofo jvb
Tras confirmar que no hay reinicios continuos, pulsa Ctrl+C para salir de los registros y luego prueba:
curl -I http://meet.example.com
curl -I https://meet.example.com
sudo ss -lntup | grep -E ':(80|443|10000)\b'
Abre https://meet.example.com en el navegador y crea una sala aleatoria. Prueba con al menos dos dispositivos en redes distintas, por ejemplo un ordenador con banda ancha y un móvil con el Wi-Fi desactivado usando datos móviles.
La conexión de Jitsi se divide aproximadamente en dos partes:
- El navegador accede a la página web, BOSH o señalización WebSocket por 443/TCP;
- El audio y el vídeo se comunican preferentemente con Jitsi Videobridge por 10000/UDP.
Por tanto, que la página de inicio y la sala abran solo demuestra que HTTPS funciona básicamente, no que la ruta de medios funcione. Al solucionar problemas, ejecuta:
sudo ufw status verbose
sudo ss -lunp | grep ':10000'
sudo docker compose logs --tail=200 jvb
También confirma el grupo de seguridad de la nube, el cortafuegos del host, las políticas UDP del operador y JVB_ADVERTISE_IPS. El proxy normal de Cloudflare no reenvía el tráfico de medios 10000/UDP de Jitsi.
La opción más simple y estable es mantener meet.example.com como DNS Only, de modo que tanto HTTPS como UDP vayan directamente al VPS. También se recomienda usar DNS Only al emitir certificados por primera vez, para reducir variables en la validación ACME.
La nube naranja de Cloudflare puede hacer proxy de páginas web y WebSocket, pero no sustituye el reenvío de medios UDP de JVB ni puede ocultar la IP de origen del servidor de medios. Asumir erróneamente que "con la nube naranja activada no hace falta abrir 10000/UDP" hará que se pueda entrar en la sala pero no hablar con normalidad.
Si realmente quieres hacer proxy de la capa web, verifica por separado:
- Si el WebSocket de
/xmpp-websocketfunciona; - Si el JVB Candidate que recibe el navegador es la IP pública correcta;
- Si 10000/UDP es directamente accesible;
- Si el modo HTTPS es Full (strict) y no Flexible.
Por defecto, un despliegue anónimo permite que cualquier visitante cree una sala, lo que puede ser abusado al exponerse a internet. Los equipos pequeños pueden habilitar la autenticación interna ya presente en la configuración de Docker:
ENABLE_AUTH=1
ENABLE_GUESTS=1
AUTH_TYPE=internal
Aplica la configuración:
cd /opt/jitsi-meet
sudo docker compose up -d
Crea una cuenta de moderador:
sudo docker compose exec prosody \
prosodyctl --config /config/prosody.cfg.lua \
register host meet.jitsi 'replace-with-a-strong-password'
Una vez habilitada, los usuarios autenticados se encargan de crear salas y los invitados pueden unirse tras la aprobación del moderador. Prueba por separado el flujo de moderador y el de invitado con un navegador de incógnito y uno normal.
La autenticación interna es adecuada para un número reducido de moderadores fijos. Cuando necesites SSO empresarial, permisos detallados o identidades de reunión emitidas por un sistema de negocio, usa una solución JWT/OIDC. El proyecto oficial ha marcado como obsoleto el antiguo proceso manual de Secure Domain; no copies tutoriales de configuración de Prosody desactualizados para sistemas nuevos.
Algunas redes corporativas, el Wi-Fi de hoteles y cortafuegos estrictos bloquean UDP o las conexiones punto a punto. En ese caso puedes desplegar Coturn para que las conexiones uno a uno se retransmitan por TURN cuando no sea posible la conexión directa.
La documentación oficial de TURN de Jitsi usa:
3478/UDP: TURN normal;5349/TCP: TURN con TLS;- Para redes especialmente estrictas se puede planificar TLS 443, pero requiere multiplexación SNI con el HTTPS web o un servidor independiente.
No escribas usuarios y contraseñas TURN estáticos directamente en la configuración del frontend. Los navegadores pueden ver estas credenciales y otros podrían robar tu tráfico de retransmisión. Una opción más robusta es usar credenciales de corta duración emitidas mediante el módulo de servicio externo de Prosody.
TURN no sustituye a 10000/UDP ni puede convertir un VPS de bajo ancho de banda en una plataforma de reuniones de alta concurrencia. Principalmente ofrece un respaldo para conexiones en redes restringidas y aumentará el tráfico de salida del servidor.
La grabación y la transmisión en directo del lado del servidor usan Jibri. Jibri lanza un navegador, renderiza la reunión, captura audio y vídeo y lo codifica, consumiendo bastantes más recursos que los componentes básicos de Jitsi.
No habilites Jibri directamente en un host de reuniones de 2 núcleos y 2GB. En producción, prepara un host separado para la grabación o al menos reserva CPU, memoria y disco dedicados, y planifica:
- El directorio y la capacidad de almacenamiento de los archivos de grabación;
- Si se informa claramente a los usuarios de que se está grabando;
- Los permisos de acceso a los archivos y los periodos de retención;
- La acumulación local cuando falla la subida al almacenamiento de objetos;
- Los límites de concurrencia para grabar varias reuniones a la vez.
Si solo necesitas un guardado personal temporal, evalúa primero la grabación local en el navegador en lugar de desplegar de inmediato un Jibri completo.
Jitsi básico no guarda el contenido de cada reunión como una aplicación de base de datos, pero los siguientes archivos determinan si puedes reconstruir rápidamente:
/opt/jitsi-meet/.env
/opt/jitsi-meet/docker-compose.yml
/opt/jitsi-meet-cfg/
Registra la versión actual y el estado de los contenedores antes de la copia de seguridad:
cd /opt/jitsi-meet
grep -m1 -o 'stable-[0-9-]*' docker-compose.yml
sudo docker compose ps
cd /
sudo tar \
--exclude='opt/jitsi-meet-cfg/tmp' \
-czf /root/jitsi-backup-$(date +%F).tar.gz \
opt/jitsi-meet/.env \
opt/jitsi-meet/docker-compose.yml \
opt/jitsi-meet-cfg
Copia las copias de seguridad a almacenamiento de objetos u otro servidor; no las dejes solo en el mismo disco del sistema. .env contiene contraseñas, por lo que los archivos de copia de seguridad deben cifrarse y restringir sus permisos. Puedes combinarlo con el tutorial de simulacro de copia de seguridad y restauración de VPS para validar el proceso de recuperación.
La recomendación oficial es volver a descargar el Release más reciente en lugar de cambiar el directorio de producción a master. Antes de actualizar, crea una instantánea del VPS y una copia de la configuración, y luego lee las Release Notes.
A partir de stable-11146, los contenedores pasan a no root y sistema de archivos de solo lectura, y se añaden los directorios storage y tmp. Al actualizar desde versiones antiguas, primero debes crear y autorizar estos directorios según la documentación oficial.
Proceso habitual de actualización:
- Descarga y descomprime el nuevo Release en un directorio nuevo;
- Compara los archivos
env.exampley Compose antiguos y nuevos; - Copia el
.envexistente y añade las variables que requiera la nueva versión; - Conserva los directorios persistentes
/opt/jitsi-meet-cfg; - Descarga las nuevas imágenes y ejecuta
docker compose up -d; - Vuelve a probar audio y vídeo con dos redes externas.
No des por completada una actualización entre versiones solo por ejecutar docker compose pull, porque la estructura de Compose, los directorios y las variables de entorno también pueden cambiar.
cd /opt/jitsi-meet
sudo docker compose ps
sudo docker compose logs --tail=200 web prosody jicofo jvb
En stable-11146 y posteriores, comprueba primero si los directorios storage y tmp existen y son escribibles por UID 1000, y después si las contraseñas internas están vacías.
dig +short meet.example.com A
sudo ss -lntp | grep -E ':(80|443)\b'
sudo docker compose logs --tail=200 web
Comprueba DNS, registros AAAA incorrectos, grupos de seguridad 80/443, el proxy de Cloudflare y la frecuencia de solicitud de certificados. Eliminar repetidamente /opt/jitsi-meet-cfg/storage/web hará perder los certificados existentes y puede activar límites de ACME.
La conexión uno a uno puede usar P2P, y al añadir una tercera persona se cambia a JVB. Revisa especialmente 10000/UDP, los registros de JVB, JVB_ADVERTISE_IPS y el grupo de seguridad de la nube.
Comprueba Prosody, Jicofo y WebSocket:
sudo docker compose logs --since=10m prosody jicofo web
curl -I https://meet.example.com/xmpp-websocket
El proxy inverso o la CDN deben admitir WebSocket Upgrade. La desincronización horaria también puede afectar a la autenticación y a los certificados; usa timedatectl status para comprobar NTP.
Los certificados autofirmados y las páginas HTTP no cumplen los requisitos de contexto seguro del navegador. Debes usar HTTPS válido y confirmar que el dominio al que accede el móvil coincide con el certificado. La documentación oficial de Jitsi también indica claramente que las aplicaciones móviles no pueden usar el certificado autofirmado predeterminado.
Primero distingue entre problemas de recursos del servidor y de red:
docker stats --no-stream
free -h
df -h
sudo ss -s
sudo docker compose logs --since=10m jvb
Observa el ancho de banda de salida del VPS, la pérdida de paquetes, el CPU Steal, las regiones de los clientes y la accesibilidad UDP. Añadir memoria por sí solo no corrige una latencia alta entre continentes ni la congestión de la línea en horas punta.
- Usar el Release estable oficial, no
masterniunstable -
PUBLIC_URLcoincide con el dominio HTTPS real -
JVB_ADVERTISE_IPSes la IP pública correcta - 80/TCP, 443/TCP y 10000/UDP están abiertos tanto en el grupo de seguridad como en UFW
- El certificado Let's Encrypt es válido y HTTP redirige automáticamente a HTTPS
- Dos dispositivos en redes distintas han completado las pruebas de audio, vídeo y compartir pantalla
- Los desconocidos no pueden crear ni abusar libremente de las salas de reunión
-
.envy el directorio de configuración están cifrados y respaldados fuera del sitio - Hay una instantánea antes de actualizar y se registra la versión estable actual
- Se ha probado TURN para compatibilidad con redes restringidas, no solo la apertura de puertos
El criterio de un despliegue correcto de Jitsi Meet no es "que la página de inicio abra", sino que redes externas puedan completar reuniones de varias personas a través de las rutas de medios HTTPS, WebSocket y UDP correctas. Primero deja bien PUBLIC_URL, JVB_ADVERTISE_IPS, 10000/UDP y los permisos de creación de salas, y luego considera grabación, transmisión en directo, SSO y escalado con varios Videobridge.