Deployment
Local operation, TLS termination, network restrictions, and independent nodes.
Release binaries
Standalone releases cover Linux x64/ARM64 glibc, macOS x64/ARM64, and Windows x64 MSVC.
Download the target .tar.gz archive and keep its LICENSE and THIRD_PARTY_NOTICES.md plus the THIRD_PARTY_LICENSES.txt appendix with the
executable. Raw binaries are also accompanied by those notices in the release assets.
Release archives include both the FFmpeg-independent administrative CLI and the separately linked server runtime. The release archives do not bundle FFmpeg. The one-command installer provisions FFmpeg 9 in an isolated directory, or you can install compatible shared libraries independently.
See runtime ABI versions and library discovery and
licensing and media responsibility. The server needs no Node.js runtime.
Docker
The published ghcr.io/twlite/remedia image and Compose example run the standalone server with persistent configuration and a loopback-only published port. See Run the server in Docker.
Local development
For local use, install the server with the installer, run
remedia init, read the generated credentials from remedia.config.json, and start remedia-server.
The listener defaults to 127.0.0.1:8787 and accepts WebSocket RPC at /v1/ws.
Discord bot identity is sent by each client as the X-Remedia-Bot-Id WebSocket handshake header.
The server configuration contains only server-side accounts and access policy, allowing one
authenticated account to serve multiple independent bot identities.
Contributors building from source can use cargo run -p remedia-server with the repository's
example configuration. See CONTRIBUTING.md.
TLS reverse proxy
The server does not terminate TLS. For remote clients, expose only a TLS reverse proxy, bind Remedia
to a private interface, and firewall the plain listener. The proxy must support WebSocket upgrades,
forward Authorization, and allow long-lived connections. Example Nginx location (with TLS server
configuration and certificates supplied by the operator):
location /v1/ws {
proxy_pass http://127.0.0.1:8787/v1/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Authorization $http_authorization;
proxy_set_header X-Remedia-Bot-Id $http_x_remedia_bot_id;
proxy_read_timeout 1h;
proxy_send_timeout 1h;
}Clients then connect to wss://media.example.net/v1/ws. Keep passwords and resume credentials in
secret storage. Do not put them in URLs, logs, shell history, or source control. The server supports
standard ws:// and wss:// clients. @remedia/client also maps remedia:// to ws:// and
remedias:// to wss://. Optional URL userinfo is stripped and sent only in the WebSocket Basic
Authorization header.
Media network policy
Use allowedFileRoots to expose only intended media directories. URL access is denied unless a host
is explicitly allowlisted. Keep blockPrivateNetworks enabled. FFmpeg may follow redirects after
the initial host check, so also restrict server egress at the host/network layer. For workloads that
accept client-selected URLs, firewall access to loopback, RFC 1918 networks, link-local addresses,
cloud metadata endpoints, and internal service networks. Use a narrow host allowlist and prefer
HTTPS.
The filtergraph API executes native FFmpeg filters. It is suitable for trusted applications and should be limited to trusted control clients. RPC authentication alone does not turn arbitrary filter expressions into a safe sandbox.
Session durability and capacity
Each process owns independent in-memory sessions. Unexpected socket loss permits resumption for a bounded timeout. Explicit close, expiry, and graceful shutdown release playback and voice resources. A process restart loses active sessions. Servers have no shared session store or cluster coordinator.
Set connection, player, message, request, and event limits to match host resources. node.stats
reports local capacity, player/connection counts, process uptime, CPU parallelism/load and resident
memory when the host exposes them, plus transport and processing health. Memory counters differ by OS and unsupported values are null. See Process resources.
Multiple nodes do not share state and do not proxy commands. @remedia/client selects a healthy
node for a new guild and routes later operations for that guild to the same node. Existing assignments stay put during outages. Applications can explicitly migrate supported URL playback to a healthy node, or restore sessions with fresh Discord credentials after loss.
Manual Discord test
The remote_discord example
connects as an RPC client, creates a guild player, uses voice credentials supplied by an external
bot Gateway implementation, plays a URL, replaces and clears filters, then stops and disconnects.
It never sends OP 4. CI does not use Discord credentials. It validates server playback through a
null output and localhost WebSocket connections.