# Deployment Guide

Source: https://docs.gryt.chat/docs/deployment

Deploy Gryt locally or in production

## Deployment options

<Cards>
  <Card
    title="Desktop App (Embedded Server)"
    description="Host a server directly from the Gryt desktop app — one click, no setup, all platforms."
    href="/docs/deployment/embedded"
  />
  <Card
    title="No domain, just an IP"
    description="Open three ports and hand out your address. No certificate, no proxy, desktop app only."
    href="/docs/deployment/no-domain"
  />
  <Card
    title="Docker Compose"
    description="Fastest way to self-host — pre-built images, no cloning, one command."
    href="/docs/deployment/docker-compose"
  />
  <Card
    title="Terminal manager (gryt CLI)"
    description="Create and run servers from a keyboard-driven terminal app. Writes the compose file for you."
    href="/docs/cli"
  />
  <Card
    title="Windows (no Docker)"
    description="Run on any Windows PC — extract a zip, edit one file, double-click start."
    href="/docs/deployment/windows"
  />
  <Card
    title="Cloudflare Tunnel"
    description="Self-host with automatic HTTPS tunnels — no port forwarding for HTTP."
    href="/docs/deployment/cloudflare-tunnel"
  />
  <Card
    title="Tailscale"
    description="Carries voice as well as chat, because WireGuard is UDP and a tunnel is not."
    href="/docs/deployment/tailscale"
  />
  <Card
    title="Monitoring"
    description="Optional Prometheus + Grafana stack for metrics and dashboards."
    href="/docs/deployment/monitoring"
  />
</Cards>

## Production requirements

<Callout type="warn">
These apply to **all** deployment methods.
</Callout>

- **HTTPS/WSS required** — browsers require a secure context for WebRTC microphone access.
- **One UDP media port** — the SFU needs `ICE_UDP_MUX_PORT` (default `3478/udp`) reachable from the internet. Every participant's media shares it.
- **JWT_SECRET** — used by the signaling server for session tokens. Generate with `openssl rand -base64 48`.

## Quick comparison

| Method | Best for | TLS | Needs open ports? |
|--------|----------|-----|-------------------|
| [Embedded (desktop app)](https://docs.gryt.chat/docs/deployment/embedded) | LAN parties, quick hosting, zero setup | N/A (local) | No (LAN only) |
| [Docker Compose](https://docs.gryt.chat/docs/deployment/docker-compose) | Self-hosting on a VPS or bare metal | Add Caddy/Nginx | Yes (443 TCP, 3478 UDP) |
| [Windows (no Docker)](https://docs.gryt.chat/docs/deployment/windows) | LAN parties, local teams, Windows PCs | Manual / reverse proxy | Yes |
| [Terminal manager](https://docs.gryt.chat/docs/cli) | A machine you administer, one or several servers | Add Caddy/Nginx | Yes |
| [Cloudflare Tunnel](https://docs.gryt.chat/docs/deployment/cloudflare-tunnel) | Hosting behind NAT / no static IP | Automatic | UDP only |
| [Tailscale](https://docs.gryt.chat/docs/deployment/tailscale) | A private group, no public exposure at all | N/A (inside the tailnet) | No |
| [No domain, just an IP](https://docs.gryt.chat/docs/deployment/no-domain) | Desktop-app users, no certificate | None | Yes |
| Kubernetes (Helm) | Scaled / multi-node clusters | cert-manager | Yes |

## Docker Compose (recommended)

Download two files, edit `.env`, and run `docker compose up -d` — no repo clone needed:

```bash
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 — at minimum set a real JWT_SECRET:
#   openssl rand -base64 48
docker compose up -d
```

See the full [Docker Compose guide](https://docs.gryt.chat/docs/deployment/docker-compose) for configuration, TLS, upgrades, and production hardening.

## Kubernetes (Helm)

```bash
helm install gryt ./ops/helm/gryt -f ops/helm/gryt/examples/production-values.yaml
```

All images are pulled from `ghcr.io/gryt-chat/*`.

## Docker images

All services are published to GitHub Container Registry under the [`gryt-chat`](https://github.com/orgs/gryt-chat/packages) org:

| Service | Image |
|---------|-------|
| Web Client | `ghcr.io/gryt-chat/client` |
| Signaling Server | `ghcr.io/gryt-chat/server` |
| SFU (Media) | `ghcr.io/gryt-chat/sfu` |
| Landing Site | `ghcr.io/gryt-chat/site` |
| Documentation | `ghcr.io/gryt-chat/docs` |

Each image is tagged with `latest` and semver tags (e.g. `1.2.3`, `1.2`, `1`). Multi-arch builds (amd64 + arm64).

## Ports

| Port | Proto | Service |
|------|------:|---------|
| `443` | TCP | TLS termination (proxy / tunnel edge) |
| `3478` | UDP | SFU WebRTC media, `ICE_UDP_MUX_PORT` |
| `3666` | TCP | Web client (dev / direct access) |
| `5000` | TCP | Signaling server |
| `5005` | TCP | SFU WebSocket |
| `3478` | UDP | SFU WebRTC media, `ICE_UDP_MUX_PORT`. Must be public |

## Health checks

All services expose a health endpoint:

```bash
curl http://localhost:5000/health   # server
curl http://localhost:5005/health   # sfu
curl http://localhost:3666/health   # client
```

## Monitoring

Both Server and SFU expose Prometheus metrics at `/metrics`. An optional
Prometheus + Grafana stack is included — see the [Monitoring guide](https://docs.gryt.chat/docs/deployment/monitoring).

## Interested in offering Gryt hosting?

<Callout type="info">
We're looking to partner with hosting and infrastructure providers who want to offer managed Gryt instances to their customers. If you're a server provider interested in adding Gryt to your platform, reach out at [sivert@gryt.chat](mailto:sivert@gryt.chat).
</Callout>
