Add docker setup and switch voice chat backend to use livekit
This commit is contained in:
226
quickstart.md
Normal file
226
quickstart.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# Quick Start: Docker
|
||||
|
||||
This guide gets Chat Grid running with Docker Compose and optionally behind a Caddy reverse proxy for HTTPS.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Browser → Caddy (TLS) → nginx:80 → static files
|
||||
└→ /ws → Python server:4474
|
||||
→ LiveKit server:7880 (signaling WebSocket)
|
||||
→ LiveKit server:7881/tcp, 7882/udp (media transport)
|
||||
```
|
||||
|
||||
nginx handles the built client files and the WebSocket proxy to the Python server. Caddy (or any reverse proxy) sits in front for TLS termination.
|
||||
|
||||
Voice audio flows through a **LiveKit SFU** (Selective Forwarding Unit) rather than direct peer-to-peer connections. The browser connects to LiveKit directly for audio, and to the Python server (via nginx) for everything else (chat, position, items, auth).
|
||||
|
||||
---
|
||||
|
||||
## 1. Prerequisites
|
||||
|
||||
- Docker with Compose plugin (`docker compose version`)
|
||||
- Git
|
||||
|
||||
---
|
||||
|
||||
## 2. Clone and Configure
|
||||
|
||||
```bash
|
||||
git clone <repo-url> chat_grid
|
||||
cd chat_grid
|
||||
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Edit `.env`:
|
||||
|
||||
```env
|
||||
# Generate a secret: openssl rand -hex 32
|
||||
CHGRID_AUTH_SECRET=your-long-random-secret-here
|
||||
|
||||
# The URL your browser uses to reach the app (no trailing slash)
|
||||
# Use http://localhost for local-only access
|
||||
CHGRID_HOST_ORIGIN=https://your-domain.com
|
||||
|
||||
# LiveKit SFU settings — keys must match livekit.yaml
|
||||
LIVEKIT_API_KEY=devkey
|
||||
LIVEKIT_API_SECRET=a]3jK$2pL9mN#vQ8wR5tY7uI0oP4sD6fG
|
||||
|
||||
# LiveKit URL as seen by the browser (not Docker-internal).
|
||||
# Local: ws://localhost:7880
|
||||
# Production behind Caddy: wss://livekit.your-domain.com
|
||||
LIVEKIT_URL=ws://localhost:7880
|
||||
```
|
||||
|
||||
### LiveKit credentials
|
||||
|
||||
The default `livekit.yaml` ships with a dev key pair (`devkey` / `a]3jK$2pL9mN#vQ8wR5tY7uI0oP4sD6fG`). For production, generate your own:
|
||||
|
||||
```bash
|
||||
# Pick any key name and a long random secret
|
||||
echo "mykey: $(openssl rand -base64 32)"
|
||||
```
|
||||
|
||||
Put the key/secret in both `livekit.yaml` (under `keys:`) and `.env` (`LIVEKIT_API_KEY` / `LIVEKIT_API_SECRET`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Build and Start
|
||||
|
||||
```bash
|
||||
docker compose up --build -d
|
||||
```
|
||||
|
||||
This builds the server and client images, pulls the LiveKit image, and starts all three containers:
|
||||
|
||||
| Container | Purpose | Ports |
|
||||
|---|---|---|
|
||||
| `client` (nginx) | Static files + WebSocket proxy | `127.0.0.1:4474 → 80` |
|
||||
| `server` (Python) | Game logic, auth, token generation | Internal only |
|
||||
| `livekit` | Audio SFU | `7880`, `7881/tcp`, `7882/udp` |
|
||||
|
||||
---
|
||||
|
||||
## 4. Bootstrap the First Admin
|
||||
|
||||
This only needs to be run once on first startup:
|
||||
|
||||
```bash
|
||||
docker compose exec server python main.py --bootstrap-admin
|
||||
```
|
||||
|
||||
Follow the prompts to create the initial admin account.
|
||||
|
||||
---
|
||||
|
||||
## 5. Open the App
|
||||
|
||||
- **Local:** http://localhost:4474
|
||||
- **With Caddy:** https://your-domain.com (after step 6)
|
||||
|
||||
Log in with the admin credentials you just created.
|
||||
|
||||
---
|
||||
|
||||
## 6. Production: Caddy Reverse Proxy (HTTPS)
|
||||
|
||||
For production you need Caddy (or another reverse proxy) in front of both nginx and LiveKit. You need **two domains** (or a domain + subdomain):
|
||||
|
||||
- One for the app (e.g. `your-domain.com`)
|
||||
- One for LiveKit (e.g. `livekit.your-domain.com`)
|
||||
|
||||
### Caddyfile
|
||||
|
||||
```caddyfile
|
||||
your-domain.com {
|
||||
reverse_proxy localhost:4474
|
||||
}
|
||||
|
||||
livekit.your-domain.com {
|
||||
reverse_proxy localhost:7880
|
||||
}
|
||||
```
|
||||
|
||||
Caddy automatically:
|
||||
- Provisions TLS certificates via Let's Encrypt
|
||||
- Forwards WebSocket upgrade headers (no extra config needed)
|
||||
- Passes app traffic (static files + `/ws`) to nginx on port 4474
|
||||
- Passes LiveKit signaling to port 7880
|
||||
|
||||
After editing your Caddyfile:
|
||||
|
||||
```bash
|
||||
caddy reload --config /etc/caddy/Caddyfile
|
||||
```
|
||||
|
||||
### Update `.env` for production
|
||||
|
||||
```env
|
||||
CHGRID_HOST_ORIGIN=https://your-domain.com
|
||||
LIVEKIT_URL=wss://livekit.your-domain.com
|
||||
```
|
||||
|
||||
Then restart the server to pick up the new LiveKit URL:
|
||||
|
||||
```bash
|
||||
docker compose up -d server
|
||||
```
|
||||
|
||||
### Firewall / port forwarding
|
||||
|
||||
The following ports must be reachable from the internet:
|
||||
|
||||
| Port | Protocol | Purpose |
|
||||
|---|---|---|
|
||||
| 443 | TCP | Caddy HTTPS (app + LiveKit signaling) |
|
||||
| 7881 | TCP | LiveKit media (TCP fallback) |
|
||||
| 7882 | UDP | LiveKit media (primary, WebRTC) |
|
||||
|
||||
If you are **not** using Caddy in front of LiveKit (i.e. clients connect to LiveKit directly without TLS), also open port **7880** (TCP).
|
||||
|
||||
> **Note:** The old peer-to-peer WebRTC setup required users to have a direct network path to each other. With LiveKit, all media goes through the server, so users behind NAT connect without issue as long as they can reach the ports above.
|
||||
|
||||
---
|
||||
|
||||
## 7. Persistence
|
||||
|
||||
User data (SQLite DB, `items.json`) is stored in a named Docker volume called `server-runtime`. It survives container restarts and rebuilds:
|
||||
|
||||
```bash
|
||||
docker compose restart # data is preserved
|
||||
docker compose up --build -d # rebuild images, data is preserved
|
||||
```
|
||||
|
||||
To inspect or back up the volume:
|
||||
|
||||
```bash
|
||||
docker volume inspect chat_grid_server-runtime
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Commands
|
||||
|
||||
```bash
|
||||
# View logs
|
||||
docker compose logs -f
|
||||
|
||||
# View server logs only
|
||||
docker compose logs -f server
|
||||
|
||||
# View LiveKit logs only
|
||||
docker compose logs -f livekit
|
||||
|
||||
# Stop everything
|
||||
docker compose down
|
||||
|
||||
# Stop and delete the data volume (destructive)
|
||||
docker compose down -v
|
||||
|
||||
# Rebuild after code changes
|
||||
docker compose up --build -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**WebSocket won't connect / "Disconnected" status**
|
||||
- Check that `CHGRID_HOST_ORIGIN` in `.env` exactly matches the URL in your browser (including `http`/`https` and no trailing slash).
|
||||
- Check server logs: `docker compose logs server`
|
||||
|
||||
**No audio / "LiveKit disconnected"**
|
||||
- Verify `LIVEKIT_URL` in `.env` is reachable from the browser (not a Docker-internal hostname like `livekit:7880`).
|
||||
- Check LiveKit logs: `docker compose logs livekit`
|
||||
- For production, make sure ports 7881/tcp and 7882/udp are open and forwarded.
|
||||
- If behind Caddy, make sure the LiveKit subdomain is configured and `LIVEKIT_URL` uses `wss://`.
|
||||
|
||||
**LiveKit secret mismatch**
|
||||
- The key/secret in `.env` (`LIVEKIT_API_KEY`/`LIVEKIT_API_SECRET`) must exactly match what is in `livekit.yaml` under `keys:`.
|
||||
|
||||
**Changing the host port**
|
||||
- The client binds to `127.0.0.1:4474` by default. To use a different port, change `"127.0.0.1:4474:80"` in `docker-compose.yml` and update your Caddy `reverse_proxy` target to match.
|
||||
|
||||
**Admin bootstrap fails**
|
||||
- Make sure the server container is healthy first: `docker compose ps`
|
||||
Reference in New Issue
Block a user