How to Make a Voice and Video Calling Website with NextCloud
Run your own Zoom with NextCloud Talk. Why two-person calls work instantly but group calls need a second server, how to set up TURN, and what it costs.
You can run your own Zoom. NextCloud Talk gives you voice calls, video calls, screen sharing and chat on your own server, with no time limits and no per-user fees.
There is one thing you must understand before you start, because it explains almost every problem people hit: two-person calls and group calls work in completely different ways. One is easy. The other needs a second server.
The difference that explains everything
| Two people | Three or more | |
|---|---|---|
| How it works | Browsers connect directly to each other | Everything routes through your server |
| Your server does | Introduces them, then steps aside | Receives and forwards every video stream |
| Needs | NextCloud + TURN | NextCloud + TURN + a signalling server |
| Server load | Almost none | Heavy |
| Setup effort | An hour | Most of a day |
With the built-in signalling, NextCloud Talk handles about four people before quality collapses. Everyone sends their video to everyone else, so four people means twelve streams. Beyond that you need a proper back end.
Start with the simple setup. If two-person calls are all you need — support calls, consultations, tutoring — you are finished in an hour.
What you need
- NextCloud already installed. If not, start with how to install NextCloud on Ubuntu with Apache2.
- A domain with a valid SSL certificate. Not optional — browsers refuse camera and microphone access on plain HTTP, and calls will fail silently with no useful error.
- A VPS with a public IP. 2 GB RAM for small calls, 4 GB or more for groups.
- Ports open — 3478 and 5349 for TURN, plus a UDP range for media.
Step 1: Install NextCloud Talk
In NextCloud, open Apps, find Talk and enable it. A chat icon appears in the top bar.
Test straight away: open a conversation and start a call in two different browsers. On the same network it will probably work. That is not proof it works — the real test comes after TURN.
Step 2: Install a TURN server
This is the step people skip, and then spend days wondering why calls ring and never connect.
Why TURN is needed
Most people are behind a home router or a mobile network that hides their real address. Two such browsers cannot find each other directly. A TURN server sits in the middle with a public address and relays the call.
Without TURN, calls work on your office Wi-Fi and fail for real users. That is exactly why it seems to work while you are testing.
Install coturn
sudo apt-get update
sudo apt-get install coturn
Enable the service:
sudo sed -i '/TURNSERVER_ENABLED/c\TURNSERVER_ENABLED=1' /etc/default/coturn
Generate a secret you will need twice — once here, once in NextCloud:
openssl rand -hex 32
Open the config:
sudo nano /etc/turnserver.conf
Put this in, replacing the IP, domain and secret with your own:
listening-port=3478
tls-listening-port=5349
listening-ip=YOUR.SERVER.IP
relay-ip=YOUR.SERVER.IP
fingerprint
use-auth-secret
static-auth-secret=YOUR_GENERATED_SECRET
realm=yourdomain.com
total-quota=100
stale-nonce
cert=/etc/letsencrypt/live/yourdomain.com/fullchain.pem
pkey=/etc/letsencrypt/live/yourdomain.com/privkey.pem
no-loopback-peers
no-multicast-peers
no-cli
Save and restart:
sudo systemctl restart coturn
sudo systemctl enable coturn
The relay-ip must be your public IP, not something like 10.0.0.5. Getting this wrong is the most common reason calls still fail after installing TURN.
Open the firewall
sudo ufw allow 3478
sudo ufw allow 5349
sudo ufw allow 49152:65535/udp
Tell NextCloud about it
Go to Administration settings → Talk. Under STUN and TURN servers add:
- Server:
yourdomain.com:3478 - Secret: the string you generated
- Protocols: UDP and TCP
Press the test button. A green tick means TURN is reachable. Do not continue until you see it.
Step 3: Test properly
The only test that counts: two devices on different networks. One on Wi-Fi, one on mobile data with Wi-Fi switched off.
Calls between two devices on the same Wi-Fi almost always work, with or without TURN. That test tells you nothing.
Step 4: Group calls (only if you need them)
For more than about four people, install the High Performance Back End — a signalling server plus an SFU, which receives every participant's video once and forwards it, instead of everyone sending to everyone.
It has three parts: the signalling server, Janus as the media server, and NATS for messaging between them. NextCloud publishes a Docker setup that installs all three together, which is far easier than assembling them by hand.
Plan on most of a day, and a server with at least 4 GB of RAM. Group video is genuinely demanding: ten people in a call can saturate a small VPS on its own.
What it costs
| Setup | Server | Cost | Handles |
|---|---|---|---|
| NextCloud + TURN | 2 GB VPS | $10–12 / month | Two-person calls, unlimited |
| Plus high performance back end | 4–8 GB VPS | $25–50 / month | Group calls, 10–30 people |
Compare with Zoom at roughly $15 per host per month. With five hosts, self-hosting pays for itself immediately — and there is no 40-minute limit.
Common problems
Calls ring, then nothing happens
TURN is missing or misconfigured. Check relay-ip is the public IP, confirm coturn is running with sudo systemctl status coturn, and use the test button in NextCloud Talk settings.
Camera and microphone never activate
The site is not on HTTPS, or the certificate is invalid. Browsers block media access on insecure origins and often give no visible error.
Calls work on Wi-Fi but not on mobile data
Classic TURN problem. Mobile networks use carrier-grade NAT, so a direct connection is impossible and the relay must work. Confirm UDP 3478 is genuinely reachable from outside.
Group calls freeze with four or more people
You are still on the built-in signalling, which does not scale. Install the High Performance Back End.
Echo or robotic audio
Usually one participant without headphones, feeding speaker output back into the microphone. If everyone sounds bad, the server is short of CPU.
Screen sharing is blank
A browser permission issue rather than a server one. On macOS the browser needs screen recording permission in System Settings.
Where to go next
NextCloud Talk also does text chat, file sharing inside conversations and a browser-based lobby for guests, so people can join a call without an account.
If you want calls inside a mobile app rather than a browser, how to create a chat app in Android Studio uses the same TURN setup with an XMPP server behind it.
And if files are really what you need, the file sharing guide covers the storage side of NextCloud.