Gryt

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 | sh
gryt

n 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.

  1. Install the desktop app
  2. Add Server, then Host a server
  3. 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.example

Edit .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.10

Leave 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 -d

That 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 -d

Ports

PortProtocolWhat
5000TCPServer: API and WebSocket
5005TCPSFU signalling WebSocket
3478UDPAll 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

  1. Install Node.js 22.13 or newer
  2. Download gryt-server-windows-x64-v*.zip from the releases page
  3. Extract it, open config.env, set SERVER_NAME
  4. 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.sh

That 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 --build

Put 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/gryt

Or from a checkout:

helm install gryt ./ops/helm/gryt \
  --set gryt.domain=yourdomain.com \
  --set server.secrets.serverPassword=your-internal-sfu-shared-secret

When 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.

On this page