You host the server; your friends connect with the desktop and Android apps. One machine, one process — no web client to run.
git clone git@github.com:SonicRelay/sonicrelay-v2.git
cd sonicrelay-v2Copy the example env file and fill in the two required values: a JWT signing secret and the public IP that voice/video traffic should connect to.
cp .env.example .env
# in .env:
ENCRYPTION_KEY= # openssl rand -base64 32 (min 32 chars)
ANNOUNCED_IP= # your server's public IP
SERVER_NAME= # display name shown in clientsWith Docker (recommended) one command starts the server on port 3000, with the database and uploads persisted in volumes:
docker compose up -dPrefer bare metal? server/setup.sh installs build deps and Node 22, generates the .env, and opens firewall ports — then npm run serve starts the server.
On your router (or VPS firewall), allow inbound traffic on the following ports to the machine running SonicRelay:
Port 3000 stays local — nginx (step 5) reverse-proxies it to HTTPS.
SonicRelay requires HTTPS. Browsers block microphone, camera, and screen sharing on plain HTTP, and passwords sent over HTTP are unencrypted.
You'll need a domain pointed at your server's public IP. If you don't want to buy one, DuckDNS hands out free subdomains that work with Let's Encrypt. Register one for the server:
Install nginx and certbot, then add a site config that reverse-proxies the subdomain to the server:
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
# required — realtime chat runs over WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}Then let certbot issue the certificate and turn on HTTPS:
sudo certbot --nginx -d api.example.comPoint your friends at the desktop and Android apps. They enter your server address (api.example.com) and pick a username and password. The first account to sign up becomes superadmin — everyone after that waits in a pending state until an admin approves them from Settings → Server Admin.
Prefer Caddy, a Cloudflare origin certificate, or another reverse proxy? Any of them work — pick what you're comfortable with.
Everything lives in two directories: server/data/ (SQLite database) and server/uploads/ (attachments, profile photos, soundboard clips). Copy those and you have a full backup — messages in the database (DMs and channels) are end-to-end encrypted, so a stolen backup can't read them.
To update: git pull then docker compose up -d --build (or rebuild and restart on bare metal). The database migrates itself forward at startup, and the desktop apps auto-update on their own.