Files
OwnCord/docs/server-configuration.md
T

215 lines
10 KiB
Markdown
Raw Normal View History

# Server Configuration Reference
Complete reference for all OwnCord server configuration options.
## Overview
OwnCord server reads configuration from `config.yaml` in the working directory. On first run, if the file does not exist, a default `config.yaml` is created automatically.
Configuration is loaded in three layers (later layers override earlier ones):
1. **Built-in defaults** (compiled into the binary)
2. **YAML file** (`config.yaml`)
3. **Environment variables** (prefix: `OWNCORD_`)
## Config Key Reference
### Server (`server`)
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `server.port` | int | `8443` | HTTP(S) listen port |
| `server.name` | string | `"OwnCord Server"` | Server display name (shown in `/api/v1/info` and admin panel) |
| `server.data_dir` | string | `"data"` | Directory for database, certs, uploads, backups |
| `server.allowed_origins` | string[] | `[]` | WebSocket CORS allowed origins; empty list DENIES all cross-origin (set to `["*"]` to allow any origin) |
| `server.trusted_proxies` | string[] | `[]` | CIDRs of trusted reverse proxies (for X-Forwarded-For) |
| `server.admin_allowed_cidrs` | string[] | private networks | CIDRs allowed to access `/admin` routes. Default: `127.0.0.0/8`, `::1/128`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` |
### TLS (`tls`)
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `tls.mode` | string | `"self_signed"` | TLS mode: `self_signed`, `acme`, `manual`, `off` |
| `tls.cert_file` | string | `"data/cert.pem"` | Path to TLS certificate (used by `manual` and `self_signed`) |
| `tls.key_file` | string | `"data/key.pem"` | Path to TLS private key |
| `tls.domain` | string | `""` | Domain for ACME/Let's Encrypt (required when `mode: acme`) |
| `tls.acme_cache_dir` | string | `"data/acme_certs"` | Directory for cached Let's Encrypt certificates |
### Database (`database`)
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `database.path` | string | `"data/chatserver.db"` | Path to SQLite database file |
### Uploads (`upload`)
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `upload.max_size_mb` | int | `100` | Maximum file upload size in megabytes |
| `upload.storage_dir` | string | `"data/uploads"` | Directory where uploaded files are stored |
### Voice / LiveKit (`voice`)
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `voice.livekit_api_key` | string | *(random per run)* | LiveKit API key. Set a stable value for persistent voice tokens. |
| `voice.livekit_api_secret` | string | *(random per run)* | LiveKit API secret (min 32 chars). Set a stable value for persistent tokens. |
| `voice.livekit_url` | string | `"ws://localhost:7880"` | LiveKit server WebSocket URL |
| `voice.livekit_binary` | string | `""` | Path to `livekit-server` binary; empty = don't auto-start |
| `voice.node_ip` | string | `""` | Public IP for WebRTC ICE candidates; empty = auto-detect. Required for remote users behind NAT. |
| `voice.quality` | string | `"medium"` | Voice quality preset: `low`, `medium`, `high` |
> **Warning:** If `livekit_api_key` or `livekit_api_secret` are left empty, random credentials are generated on each startup. This means voice tokens break on restart. Always set stable credentials in production. See [LiveKit Setup](livekit-setup.md) for details.
### GitHub / Updates (`github`)
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `github.token` | string | `""` | Optional GitHub API token for higher rate limits on update checks (5000 req/hr vs 60) |
| `github.owner` | string | `"J3vb"` | Owner of the GitHub repository server and client updates are fetched from |
| `github.repo` | string | `"OwnCord-releases"` | Public releases repository. Must stay publicly readable — both the server self-update and the client auto-update chain fetch release assets from it |
### Event Persistence (`event_persistence`)
Controls the tiered event log used for WebSocket reconnection replay. When enabled, missed events are stored in the database so clients that reconnect after the in-memory ring buffer window (1 000 events) can still replay missed events from the DB tier.
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `event_persistence.enabled` | bool | `true` | Enable cold-storage event persistence. When `false`, only the in-memory ring buffer is used (lower durability). |
| `event_persistence.retention_hours` | int | `24` | How long persisted events are kept before the pruner deletes them |
| `event_persistence.batch_size` | int | `50` | Maximum events per database flush |
| `event_persistence.batch_flush_ms` | int | `100` | Maximum delay between flushes (milliseconds) |
| `event_persistence.pruner_interval_minutes` | int | `60` | How often the pruner goroutine wakes up to delete expired events |
### Telemetry / OpenTelemetry (`telemetry`)
Controls the OpenTelemetry SDK. Requires building with `-tags otel` (see [Contributing](contributing.md)). When disabled, the server uses no-op tracer/meter providers; the legacy JSON `/api/v1/metrics` endpoint is always available regardless of this setting.
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `telemetry.enabled` | bool | `false` | Enable the OTel SDK |
| `telemetry.exporter` | string | `"none"` | Exporter backend: `none`, `prometheus`, `otlp` |
| `telemetry.otlp_endpoint` | string | `""` | gRPC endpoint for the OTLP exporter (e.g. `localhost:4317`). Only used when `exporter: otlp`. |
| `telemetry.service_name` | string | `"owncord-server"` | OTel `service.name` resource attribute |
> **Local development:** Run `make otel-up` (from `Server/`) to start Jaeger + Prometheus via Docker.
> Jaeger UI: `http://localhost:16686` — Prometheus UI: `http://localhost:9090`
### Plugins (`plugins`)
Controls the Wazero WASM plugin runtime. Requires building with `-tags wazero`. When disabled, no plugins are loaded and the plugin admin endpoints return `501 Not Implemented`.
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `plugins.enabled` | bool | `false` | Enable plugin loading at startup |
| `plugins.directory` | string | `"data/plugins"` | Directory scanned for plugin packages on startup |
| `plugins.max_memory_mb` | int | `64` | Maximum WASM linear memory per plugin (megabytes) |
| `plugins.cpu_budget_ms` | int | `100` | Maximum CPU time per plugin invocation (milliseconds) |
| `plugins.http_allowlist` | string[] | `[]` | Host suffixes plugins may reach via the `host_http` capability (e.g. `["api.steampowered.com"]`). Empty = no outbound HTTP. |
## Environment Variable Overrides
Every config key can be overridden via environment variables using the prefix `OWNCORD_`.
**Format:** `OWNCORD_<SECTION>_<KEY>`
| Environment Variable | Config Path |
|---------------------|-------------|
| `OWNCORD_SERVER_PORT` | `server.port` |
| `OWNCORD_SERVER_NAME` | `server.name` |
| `OWNCORD_SERVER_DATA_DIR` | `server.data_dir` |
| `OWNCORD_DATABASE_PATH` | `database.path` |
| `OWNCORD_TLS_MODE` | `tls.mode` |
| `OWNCORD_TLS_CERT_FILE` | `tls.cert_file` |
| `OWNCORD_TLS_DOMAIN` | `tls.domain` |
| `OWNCORD_UPLOAD_MAX_SIZE_MB` | `upload.max_size_mb` |
| `OWNCORD_UPLOAD_STORAGE_DIR` | `upload.storage_dir` |
| `OWNCORD_VOICE_LIVEKIT_API_KEY` | `voice.livekit_api_key` |
| `OWNCORD_VOICE_LIVEKIT_API_SECRET` | `voice.livekit_api_secret` |
| `OWNCORD_VOICE_LIVEKIT_URL` | `voice.livekit_url` |
| `OWNCORD_VOICE_NODE_IP` | `voice.node_ip` |
| `OWNCORD_VOICE_QUALITY` | `voice.quality` |
| `OWNCORD_GITHUB_TOKEN` | `github.token` |
| `OWNCORD_EVENT_PERSISTENCE_ENABLED` | `event_persistence.enabled` |
| `OWNCORD_EVENT_PERSISTENCE_RETENTION_HOURS` | `event_persistence.retention_hours` |
| `OWNCORD_TELEMETRY_ENABLED` | `telemetry.enabled` |
| `OWNCORD_TELEMETRY_EXPORTER` | `telemetry.exporter` |
| `OWNCORD_TELEMETRY_OTLP_ENDPOINT` | `telemetry.otlp_endpoint` |
| `OWNCORD_TELEMETRY_SERVICE_NAME` | `telemetry.service_name` |
| `OWNCORD_PLUGINS_ENABLED` | `plugins.enabled` |
| `OWNCORD_PLUGINS_DIRECTORY` | `plugins.directory` |
## Example config.yaml
```yaml
# OwnCord Server Configuration
server:
port: 8443
name: "OwnCord Server"
data_dir: "data"
allowed_origins: [] # empty = deny all cross-origin; set to ["*"] to allow any
trusted_proxies: [] # e.g. ["10.0.0.0/8"] if behind a reverse proxy
admin_allowed_cidrs:
- "127.0.0.0/8"
- "::1/128"
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
database:
path: "data/chatserver.db"
tls:
mode: "self_signed" # self_signed | acme | manual | off
cert_file: "data/cert.pem"
key_file: "data/key.pem"
domain: "" # required for acme mode
acme_cache_dir: "data/acme_certs"
upload:
max_size_mb: 100
storage_dir: "data/uploads"
voice:
livekit_api_key: "your-api-key"
livekit_api_secret: "your-secret-at-least-32-characters-long"
livekit_url: "ws://localhost:7880"
livekit_binary: "" # path to livekit-server binary
node_ip: "" # public IP for remote users behind NAT
quality: "medium" # low | medium | high
github:
token: "" # optional GitHub PAT for update check rate limits
owner: "J3vb" # update source repo owner
repo: "OwnCord-releases" # public releases repo (binaries + source snapshots)
# Event persistence (tiered reconnect replay)
event_persistence:
enabled: true
retention_hours: 24
batch_size: 50
batch_flush_ms: 100
pruner_interval_minutes: 60
# OpenTelemetry (requires build tag: -tags otel)
telemetry:
enabled: false
exporter: "none" # none | prometheus | otlp
otlp_endpoint: "" # e.g. "localhost:4317" for OTLP gRPC
service_name: "owncord-server"
# Plugin runtime (requires build tag: -tags wazero)
plugins:
enabled: false
directory: "data/plugins"
max_memory_mb: 64
cpu_budget_ms: 100
http_allowlist: [] # host suffixes plugins may reach, e.g. ["api.steampowered.com"]
```
## See Also
- [Deployment Guide](deployment.md) -- production deployment guide
- [LiveKit Setup](livekit-setup.md) -- voice/video setup
- [Quick Start](quick-start.md) -- getting started