If you are hosted by us, this is already pre-configured on your site. This guide is for admins self-hosting Discourse.
Discourse Live uses WebRTC for voice and video calls. It ships with public STUN servers to help participants connect directly. Admins can replace those servers and add TURN to support networks where direct connections fail.
For a server dedicated to your community, we recommend running coturn as both your STUN and TURN server, with shared-secret authentication for TURN. This provides public-address discovery and a relay fallback without distributing a permanent TURN password or relying on third-party STUN servers.
This guide applies to Live’s peer-to-peer calls. Rooms using LiveKit use LiveKit’s own ICE/TURN configuration instead. Learn about Live’s LiveKit configuration.
What do STUN and TURN do?
- STUN helps a browser discover its public IP address and port so it can attempt a direct connection.
- TURN relays media when a direct connection cannot be established.
A browser that learns its public address can offer it as a server-reflexive (srflx) candidate, which is what makes direct connections through home and office NATs possible. Without one, most calls fall back to the TURN relay, adding latency and relay bandwidth.
STUN must stay open even when you run TURN. A TURN allocation response also contains the browser’s public address, but only some browsers (such as Firefox) use it as a candidate. Chromium-based browsers and Safari only learn their public address from a separate STUN Binding request, and browsers never attach credentials to Binding requests. If the server disables STUN (no-stun) or requires authentication for it (secure-stun), those browsers get no srflx candidate and every call they join is relayed.
With shared-secret TURN configured, Live allows both direct and relayed connections. Configuring TURN does not force every call through the relay. Live’s ICE configuration.
1. Prepare a TURN server
You can use a managed TURN service that supports TURN REST API shared-secret authentication, or run coturn yourself.
For a self-hosted setup, prepare:
- A server with a public IP address and sufficient bandwidth for relayed calls.
- A hostname such as
turn.example.com, pointing directly to that server. - Firewall access for its TURN listener and UDP relay port range.
- A valid certificate if you offer TURN over TLS.
Participants’ browsers connect to TURN directly. An ordinary HTTP reverse proxy or CDN proxy cannot carry TURN traffic.
Example coturn configuration
Generate a random secret:
openssl rand -hex 32
Keep the result private. You will enter the same value in coturn and Discourse.
On a server with a directly assigned public IP, use the following as a starting point in /etc/turnserver.conf:
listening-port=3478
fingerprint
realm=turn.example.com
use-auth-secret
static-auth-secret=REPLACE_WITH_YOUR_RANDOM_SECRET
# Do not add no-stun or secure-stun: browsers send STUN Binding requests
# without credentials, and many rely on them to discover their public address.
min-port=49152
max-port=65535
no-multicast-peers
# This example starts without TLS.
no-tls
no-dtls
Replace the hostname and secret, protect the configuration file, and restart coturn. Remove any conflicting no-auth or static user= configuration. Coturn’s shared-secret mode enables the authentication mechanism it needs internally. Coturn configuration reference.
Anonymous STUN only reports a client’s own address back to it; it cannot relay traffic, so it does not turn your server into an open relay. Recent coturn versions keep the optional RFC 5780 and MAPPED-ADDRESS response attributes off by default, which keeps Binding responses close to request size and limits their usefulness for reflection attacks. Leave rfc5780 and stun-backward-compatibility disabled.
Allow inbound traffic to:
| Port | Protocol | Purpose |
|---|---|---|
3478 |
UDP | STUN and TURN |
3478 |
TCP | TURN |
49152–65535 |
UDP | Relayed media |
Allow the corresponding outbound traffic too. The relay range must match min-port and max-port.
If the server sits behind NAT, configure coturn’s external-ip=PUBLIC_IP/PRIVATE_IP mapping and forward the listener and relay ports. Relay ports must retain their port numbers through NAT. Coturn deployment options.
Add TLS for restrictive networks
TURN over TLS provides another connection option for participants whose networks block UDP.
Remove no-tls and configure:
tls-listening-port=5349
cert=/path/to/fullchain.pem
pkey=/path/to/privkey.pem
Open 5349/TCP, ensure coturn can read the certificate and key, and restart it after certificate renewals.
You can use 443/TCP instead if that port is available on the TURN server. This may help on restrictive networks, although some networks also inspect and block non-HTTP traffic on port 443. The UDP relay range is still required when browsers reach TURN over TCP or TLS. Coturn server documentation.
2. Configure Discourse
In Admin → Settings, search for these Live settings:
| Setting | Value |
|---|---|
live_stun_servers |
Your coturn server’s STUN URI — replace the default entries |
live_turn_secret |
The value used for coturn’s static-auth-secret |
live_turn_secret_servers |
Your TURN URIs, separated by | |
live_turn_servers |
Empty |
live_turn_username |
Empty |
live_turn_credential |
Empty |
For the configuration above, enter this in live_stun_servers:
stun:turn.example.com:3478
And this in live_turn_secret_servers:
turn:turn.example.com:3478?transport=udp|turn:turn.example.com:3478?transport=tcp
If you enabled TLS, add its endpoint:
turn:turn.example.com:3478?transport=udp|turn:turn.example.com:3478?transport=tcp|turns:turn.example.com:5349?transport=tcp
Use stun:, turn: and turns: URIs, without //. Only list endpoints your server actually supports.
Chromium-based browsers also send STUN requests to the TURN servers you list, so an empty live_stun_servers can work as long as coturn answers anonymous STUN. Listing the STUN URI explicitly makes the setup clearer, covers other browsers, and lets Live’s connection diagnostics test it on its own.
The live_turn_secret_servers list uses credentials generated from the shared secret. The separate live_turn_servers list uses a fixed username and password. Live setting definitions.
Save the settings, then have participants leave and rejoin calls to obtain the new configuration.
3. Verify the setup
Test with two participants on different networks, such as home broadband and mobile data, and in more than one browser — at least one Chromium-based browser and Firefox. Confirm audio works in both directions, then test video and screen sharing.
While in a peer-to-peer room, open the room’s ⋮ menu and choose Connection diagnostics:
- Under STUN/TURN servers, each server should show Reachable. TURN servers should list a Relay address, and UDP servers should list a Public address. “Public address: None” means STUN requests got no answer — check for
no-stun/secure-stunand that3478/UDPis open. - Under Peers, the route shows how each connection carries media: Direct (same network), Direct (through NAT via STUN), or Relayed through TURN. Most participants on ordinary home networks should connect directly.
- Copy report produces a text report you can share with whoever is troubleshooting. It includes participants’ IP addresses, so share it privately.
In Chromium browsers, chrome://webrtc-internals shows the same details at a lower level:
- A
srflxcandidate represents a discovered public address. - A
relaycandidate represents an available TURN relay. - The selected candidate pair shows the connection actually carrying media.
A successful direct call does not prove relaying works. Also test from a network that requires TURN, or use a WebRTC test client with iceTransportPolicy: "relay" and temporary credentials.
Check coturn’s logs for successful authenticated allocations. Requests without valid credentials must not obtain a relay allocation. An initial 401 authentication challenge is normal; repeated authentication failures need investigation.
Keep the server dedicated to your community
The shared secret stays on Discourse and the TURN server. Participants receive temporary credentials instead. Live currently generates credentials valid for creating allocations for 12 hours; an established allocation can continue while it is refreshed. Live’s credential generation.
This prevents an anonymous open relay, but TURN credentials are not tied to a browser origin: a participant can copy and reuse their temporary credentials. To limit abuse:
- Restrict Live access to the intended groups.
- Monitor relay bandwidth and allocation counts.
- Set coturn allocation quotas and bandwidth limits appropriate to your community.
- Block relay access to private, link-local, and other internal destinations reachable from the TURN host.
- Keep coturn updated and rotate the shared secret if it is exposed.
Use a dedicated secret for this Discourse deployment. Your server will also answer anonymous STUN requests from anyone; this is expected, uses little bandwidth, and does not grant relay access. Coturn authentication and access controls.
Alternatives
Replace only the public STUN servers
Set live_stun_servers to your own STUN URIs, separated by |:
stun:stun.example.com:3478
Leave the TURN settings empty if you do not need a relay. STUN alone cannot make calls work on every network.
Use TURN with a fixed username and password
If your provider does not support shared-secret authentication, configure live_turn_servers, live_turn_username, and live_turn_credential. Leave the shared-secret settings empty.
Participants receive those fixed credentials, which makes them easier to reuse outside your site. Also, Live currently forces relay connections when static TURN servers are configured and the STUN list is empty. Prefer shared-secret authentication when your provider supports it. Live’s ICE configuration.