This annex provides a comprehensive guide to configuring and troubleshooting a TURN server for Jitsi Meet stable-10008 when self-hosting behind Carrier-Grade NAT (CGNAT) using Localtunnel. It ensures media traffic (audio/video) works reliably despite network restrictions, aligning with the Docker-based setup in the main walkthrough.
- CGNAT Constraints: Your mobile hotspot uses CGNAT, meaning your server lacks a public IP for direct inbound connections. Jitsi’s Videobridge (JVB) relies on UDP port 10000 for media, which CGNAT blocks.
- Localtunnel Limitation: Localtunnel tunnels TCP traffic (e.g., HTTP on port 8000), but JVB’s UDP traffic can’t be tunneled this way. A TURN server relays media over TCP or TLS, bridging this gap.
- Stable-10008: This version of Jitsi Meet supports TURN natively, with no deprecated TCP harvester options (removed in earlier releases), making TURN configuration essential for CGNAT setups.
For stable-10008, you can use:
- Public TURN Server: Free, pre-configured servers like
openrelay.metered.ca
for testing. - Self-Hosted Coturn: Deploy your own TURN server on a VPS with a public IP for full control.
- Commercial TURN: Services like Metered.ca or Twilio for scalability and reliability (not free).
This annex focuses on a public TURN server for simplicity, with notes on self-hosting.
In docker-jitsi-meet
stable-10008, TURN configuration is set via the .env
file. The valid variables (per the official repo and env.example
) are:
TURN_HOST
: Hostname of the TURN server (UDP/TCP).TURN_PORT
: Port for TURN (default 3478).TURNS_HOST
: Hostname for TURN over TLS.TURNS_PORT
: Port for TURN over TLS (default 5349 or 443).TURN_CREDENTIALS
: Username and password inusername:password
format.
Note: Variables like ENABLE_TURN
or TURN_RELAY_*
are not supported and should not be used.
Using the free openrelay.metered.ca
TURN server:
# In .env
TURN_HOST=openrelay.metered.ca
TURN_PORT=80
TURNS_HOST=openrelay.metered.ca
TURNS_PORT=443
TURN_CREDENTIALS=openrelayproject:openrelayprojectsecret
- Why This Server?: It supports TURN over TCP (port 80) and TLS (port 443), which are compatible with CGNAT and Localtunnel’s TCP-only tunneling.
- Credentials: Publicly available for testing; replace with your own for production.
Update your .env
from the main walkthrough:
# Basic Jitsi settings
CONFIG=/home/your-username/.jitsi-meet-cfg
HTTP_PORT=8000
TZ=UTC
DISABLE_HTTPS=1
PUBLIC_URL=https://your-jitsi.localtunnel.me
DOCKER_HOST_ADDRESS=172.18.x.x # Your WSL IP
# TURN server settings
TURN_HOST=openrelay.metered.ca
TURN_PORT=80
TURNS_HOST=openrelay.metered.ca
TURNS_PORT=443
TURN_CREDENTIALS=openrelayproject:openrelayprojectsecret
-
Restart Jitsi after updating:
docker-compose down && docker-compose up -d
- Frontend Config: The
web
container uses these.env
variables to populateconfig.js
with TURN server details, enabling clients to relay media when direct UDP fails. - Videobridge: The
jvb
container doesn’t directly manage TURN but relies on clients using the TURN server for media relay. - Stable-10008 Updates: No significant TURN-related changes from stable-9955 to stable-10008 (per changelog), ensuring this config remains current.
-
Check Logs:
-
Videobridge logs:
docker logs jitsi_jvb_1
Look for successful ICE candidate establishment via TURN.
-
Web logs:
docker logs jitsi_web_1
Confirm TURN server details are loaded.
-
-
Join a Meeting:
- Use
https://your-jitsi.localtunnel.me
in a browser and your React Native app. - Test audio/video across different devices/networks (e.g., mobile data vs. Wi-Fi).
- Use
-
Browser Dev Tools:
- In Chrome, go to
chrome://webrtc-internals
during a call. Look forturn:
candidates in the ICE connection stats, indicating TURN usage.
- In Chrome, go to
-
TURN Server Unreachable:
- Symptoms: No audio/video; logs show ICE failures.
- Fix: Verify
TURN_HOST
andTURNS_HOST
are correct and reachable (ping openrelay.metered.ca
from WSL). - Test:
curl -v telnet://openrelay.metered.ca:80
(should connect).
-
Invalid Credentials:
- Symptoms: Logs mention authentication errors.
- Fix: Double-check
TURN_CREDENTIALS
format (username:password
).
-
Media Still Fails:
- Cause: Public TURN server overloaded or incompatible.
- Fix: Switch to another server (e.g.,
turn:turn.matrix.org:3478
withmatrix:matrix
) or self-host.
-
Check JVB Config:
docker exec jitsi_jvb_1 cat /config/sip-communicator.properties
Ensure no conflicting settings (e.g.,
DISABLE_TCP_HARVESTER
should not be present in stable-10008). -
Inspect Config.js:
docker exec jitsi_web_1 cat /config/config.js
Look for
turncredentials
orstunServers
entries reflecting your TURN settings.
For production or if public servers fail:
-
Setup VPS: Use a provider like DigitalOcean ($5/month) with Ubuntu 22.04.
-
Install Coturn:
sudo apt update && sudo apt install -y coturn
-
Configure Coturn (
/etc/turnserver.conf
):listening-port=3478 tls-listening-port=443 external-ip=YOUR_VPS_PUBLIC_IP realm=your-turn-domain.com user=testuser:testpass cert=/etc/letsencrypt/live/your-turn-domain.com/fullchain.pem pkey=/etc/letsencrypt/live/your-turn-domain.com/privkey.pem
- Get SSL certs with Certbot:
sudo certbot certonly --standalone -d your-turn-domain.com
.
- Get SSL certs with Certbot:
-
Start Coturn:
sudo systemctl enable coturn && sudo systemctl start coturn
TURN_HOST=your-turn-domain.com
TURN_PORT=3478
TURNS_HOST=your-turn-domain.com
TURNS_PORT=443
TURN_CREDENTIALS=testuser:testpass
-
Use TLS: Prefer
TURNS_HOST
and port 443 for security and broader compatibility. -
Monitor Usage: Public TURN servers may throttle; check logs for relay usage.
-
Fallback STUN: Add STUN servers in
config.js
(manual override) if needed:stunServers: [ { urls: 'stun:stun.l.google.com:19302' } ]
This annex ensures your TURN setup is fully compatible with Jitsi Meet stable-10008, addressing your CGNAT and Localtunnel constraints. Let me know if you need help testing or tweaking it further!