Quick Start
Getting a Gryt server running
To try Gryt without hosting anything, app.gryt.chat is the web client. Push-to-talk that works while the window is in the background needs the desktop app; a browser cannot do it.
There are four ways to run a server, and they suit different things.
The CLI
One command installs it, one command builds a server with working voice and uploads.
curl -fsSL https://get.gryt.chat | shgrytn makes a server. It asks eight questions with sensible defaults, writes the
Compose files, picks ports nothing else is holding, and starts a shared SFU and
object store the first time. After that the same screen starts, stops, restarts
and follows the logs of every server on the machine, and c changes the
settings that live in a running server's database.
This is the least fiddly path for a machine you administer. Full details on the CLI page.
The desktop app
No separate software at all. Good for a LAN party or a few people.
- Install the desktop app
- Add Server, then Host a server
- Name it, Create server
It starts and connects you. Others on the same network find it over mDNS without being given an address, which Discoverable on LAN controls. Start automatically with app brings it back on every launch.
For anything internet-facing, use Compose or the CLI instead.
Docker Compose
mkdir gryt && cd gryt
curl -Lo docker-compose.yml https://raw.githubusercontent.com/Gryt-chat/gryt/main/ops/deploy/compose/prod.yml
curl -Lo .env https://raw.githubusercontent.com/Gryt-chat/gryt/main/ops/deploy/compose/.env.exampleEdit .env:
SERVER_NAME=My Gryt Server
JWT_SECRET= # openssl rand -base64 48
# Where browsers should reach the SFU. wss:// with a domain, or ws://<ip>:5005
SFU_PUBLIC_HOST=wss://sfu.example.com
# The single UDP port media flows over. Open this.
ICE_UDP_MUX_PORT=3478
# Only if the SFU is behind NAT and you know the address to advertise
ICE_ADVERTISE_IP=203.0.113.10Leave STUN on
DISABLE_STUN=true looks like a reasonable thing to set once you have given the
SFU an explicit address, and it is the single most reliable way to break voice
for everybody outside your network.
Docker and most cloud networking rewrite the UDP source port. When they do, the address the SFU thinks it has and the address the world can reach are different, and STUN is the only thing that finds the second one. Turning it off is safe only with a direct, port-preserving path out: host networking, bare metal, or a 1:1 NAT.
docker compose up -dThat brings up the server, the SFU and MinIO. The database is SQLite inside the server's data directory, so there is no database container.
To serve the web client too:
docker compose --profile web up -dPorts
| Port | Protocol | What |
|---|---|---|
5000 | TCP | Server: API and WebSocket |
5005 | TCP | SFU signalling WebSocket |
3478 | UDP | All WebRTC media, one port |
SERVER_PORT, SFU_PORT and ICE_UDP_MUX_PORT change them. 3478 is the
default everywhere: the SFU itself, the CLI and these compose files. It is the
STUN port, which is the one a corporate or school firewall has most likely
already opened.
Media is UDP. It does not go through a reverse proxy or a tunnel, and it has to reach the SFU host directly.
Windows, without Docker
- Install Node.js 22.13 or newer
- Download
gryt-server-windows-x64-v*.zipfrom the releases page - Extract it, open
config.env, setSERVER_NAME - Run
start.bat
Connect at localhost:5000. The Windows guide covers
firewall rules and reaching it from other machines.
Connecting
The desktop app takes a bare address: 203.0.113.10:5000, or a hostname.
app.gryt.chat needs a hostname with a certificate. A browser will not open an insecure connection from an HTTPS page, so a plain IP does not work there. No domain, just an IP covers the ways around that.
The first person to join a new server becomes its owner. After that it is invite-only, and invites come from Server settings → Invites.
For a LAN party, Allow anyone on LAN to join in Server settings → Overview lets anybody on the local network in without a code. People from outside still need one.
From source
git clone --recurse-submodules https://github.com/Gryt-chat/gryt.git
cd gryt
ops/start_dev.shThat runs MinIO, the SFU, two servers and the Vite client in a tmux session, and the client is on localhost:3666.
Behind a tunnel
cp ops/deploy/host/.env.example ops/deploy/host/.env
docker compose -f ops/deploy/host/compose.yml up -d --buildPut your tunnel token in the .env first. The tunnel carries HTTP and
WebSockets, so it handles signalling; the media port still has to be exposed
directly. See the Cloudflare Tunnel guide.
Kubernetes
helm install gryt oci://ghcr.io/gryt-chat/charts/grytOr from a checkout:
helm install gryt ./ops/helm/gryt \
--set gryt.domain=yourdomain.com \
--set server.secrets.serverPassword=your-internal-sfu-shared-secretWhen it does not work
Voice is the part that fails, and it nearly always fails the same way: everybody on the local network is fine, everybody else sits on "connecting". That is the media port not being reachable, or STUN being off. The voice debugging page walks through it.
- Configuration — every setting
- Docker Compose guide — TLS, upgrades, monitoring
- Architecture — what the pieces are
- Troubleshooting