Going live on a domain
Loopback evaluation needs none of this. The moment your server has a real hostname, two independent things become mandatory: TLS for the web side, and a reachable address for the media side. Doing the first and assuming it covered the second is the common way to end up with working sign-in and silent calls.
1. TLS: set the hostname and you are done
Section titled “1. TLS: set the hostname and you are done”The desktop refuses any non-loopback server that is not https://, so without TLS nobody
can sign in. That is a loud failure, which is the good kind.
The bundle’s gateway already owns ports 80/443 and gets its own Let’s Encrypt certificate
and renews it. Point an A record at the box, then in .env:
PUBLIC_HOST=teamhud.example.comPUBLIC_BASE_URL=https://teamhud.example.comAPP_URL=https://teamhud.example.comLIVEKIT_PUBLIC_URL=wss://teamhud.example.comfirstboot.sh sets all four when you give it a hostname.
2. Media: NODE_IP must be reachable by clients
Section titled “2. Media: NODE_IP must be reachable by clients”NODE_IP is the address the media server advertises to clients. Left at 127.0.0.1, calls
connect and carry no audio or video, and nothing logs an error. Set it to the box’s
public IP (or its LAN IP for an office-only install).
3. Firewall
Section titled “3. Firewall”| Port | Protocol | Why |
|---|---|---|
| 80 | TCP | Certificate issuance and the redirect to HTTPS |
| 443 | TCP | Web, API, sign-in, and call signalling (wss://) |
| 7882 | UDP | Call media, the normal path |
| 7881 | TCP | Call media for clients whose network blocks UDP |
| 3478 | UDP | TURN, for clients behind strict NAT |
| 30000–30063 | UDP | TURN relay ports. Without them TURN is advertised but carries nothing |
Nothing else needs to be public. The API, database and media signalling ports are bound to loopback on purpose.
4. TURN, and what it covers
Section titled “4. TURN, and what it covers”TURN is on in this bundle, over UDP 3478. That covers users behind symmetric NAT (many home routers and mobile hotspots).
It does not cover networks that allow only outbound TCP 443, which some corporate firewalls enforce. There a call connects and carries nothing, unless you switch on TURN over TLS on 443. It is off by default; Corporate network requirements covers it. Before you promise it works, test from a machine inside that network. The probe needs only Node and this one file from the bundle:
node verify-turn.mjs teamhud.example.com 34785. Who can reach admin, and who can sign up
Section titled “5. Who can reach admin, and who can sign up”ADMIN_IP_ALLOWLIST:/adminanswers 404 to everyone else. Unset means nobody can reach it, which is safe and confusing. Comma-separated IPs or IPv4 CIDRs.SIGNUP_MODE:open(default: anyone can sign up),sso_only(only through Sign in with Slack; see Slack), orclosed(invite-only: a new person needs an invitation sent to their email address, or a System admin creates the account). Apply it withdocker compose up -d, which restarts the auth service too.- Invite emails need a Resend key (
RESEND_API_KEY). Without one, invitations still work as shareable links; only the email is skipped.
6. Host tuning
Section titled “6. Host tuning”The media server wants a bigger UDP receive buffer than Linux’s default. Compose cannot
set it, so firstboot.sh does: it raises net.core.rmem_max to 5000000 now and for later boots.
Check it with sysctl net.core.rmem_max. If firstboot ran without root and said so, set it yourself:
echo 'net.core.rmem_max=5000000' | sudo tee /etc/sysctl.d/90-teamhud-livekit.confsudo sysctl --systemChecklist
Section titled “Checklist”- DNS A record → the box.
PUBLIC_HOST,PUBLIC_BASE_URL,APP_URL,LIVEKIT_PUBLIC_URLset. NODE_IPis the address clients reach.- Firewall opened per the table above.
ADMIN_IP_ALLOWLISTandSIGNUP_MODEchosen../verify-stack.shgreen, and a test call between two machines on different networks has audio both ways.- Backups installed and one restore tested.