This guide explains how Ferrex is configured for local development and self‑hosting. It complements the quickstart in the README and the reference .env.example.
- Generated environment file:
.envin the project root (created byjust startorjust config). - Example reference:
.env.example(kept in repo). - Derived assets and caches:
cache/ - Optional demo seed data:
demo/(when using demo mode)
Back up .env if you keep long‑lived credentials. The generator creates strong Postgres/Redis passwords.
These are the most commonly used variables. See .env.example for the authoritative list.
TMDB_API_KEY– Required for metadata lookups.SERVER_HOST/SERVER_PORT– Bind address and port (defaults:0.0.0.0/3000).FERREX_SERVER_URL– The URL clients use to reach the server (e.g.,http://localhost:3000).DATABASE_URL– Postgres connection URL (host/local use) plusDATABASE_URL_CONTAINERfor in-container commands.REDIS_URL– Redis connection URL (plusREDIS_URL_CONTAINERfor in-container access).RUST_LOG– Server logging filter, e.g.sqlx=trace,ferrex=debug.FERREX_MPV_PATH– Optional override for mpv path on Windows if auto‑detection fails.- TLS options – Paths can be provided via env (if you terminate TLS at the app). If you use a reverse proxy, terminate TLS there instead.
- Player URL – Run the player against a custom server with
FERREX_SERVER_URL=https://host:port.
From the repo root:
# Generate/refresh config without starting services
just config
# Start the full stack (DB, Redis, ferrex-server)
just start
# (same as: ferrexctl stack up)
# Bring the stack down:
# ferrexctl stack down
# Run the desktop player (release profile)
just run-player-releasedocker-compose.ymlis the default self-host stack and pulls the published server image.docker-compose.dev.ymladds a local build offerrex-server(used byjustviaFERREX_COMPOSE_FILES).docker-compose.perf.ymlenables the Postgres performance preset (huge pagestry, io_uring, larger buffers).
Unraid: see docs/unraid.md.
This repo includes a flake for local development and for running the player with a pinned Linux GStreamer build.
# dev shell
nix develop
# run player (NixOS-friendly)
nix run .#ferrex-playerFerrex defines useful build profiles for faster iteration and improved runtime performance:
- Development:
just start --profile dev(faster compile times) - Priority:
just start --profile priority(optimize workspace crates; recommended for the player) - Release:
just run-player-releaseorjust run-server-release
The ferrex-player benefits noticeably from optimization.
Run the stack with the Tailscale sidecar; no extra .env is required:
just start --mode tailscalejust start --mode tailscale automatically overrides the container endpoints to 127.0.0.1 for Postgres and Redis inside the shared Tailnet namespace while keeping your base .env intact.
Control server verbosity via --rust-log:
just start --rust-log 'sqlx=trace,ferrex=debug'Alternatively, set RUST_LOG directly in .env.
Ferrex includes a feature‑gated demo mode that seeds disposable libraries for exploration and testing. See docs/demo-mode.md for full details and environment variables.
Ferrex supports configurable Postgres performance presets for different hardware configurations:
Use FERREX_POSTGRES_PRESET to select a predefined configuration:
small(4-8GB RAM): shared_buffers=512MB, effective_cache_size=2GB, work_mem=16MB, max_connections=50medium(16-32GB RAM): shared_buffers=4GB, effective_cache_size=12GB, work_mem=64MB, max_connections=100large(64GB+ RAM): shared_buffers=16GB, effective_cache_size=48GB, work_mem=256MB, max_connections=200custom: Use individual environment variables (see below)
# During initial setup
ferrexctl init --postgres-preset=medium
# Or set manually in .env
FERREX_POSTGRES_PRESET=mediumYou can override specific parameters regardless of preset:
FERREX_POSTGRES_SHARED_BUFFERS- Shared memory for Postgres (e.g., "4GB")FERREX_POSTGRES_EFFECTIVE_CACHE_SIZE- OS cache estimate (e.g., "12GB")FERREX_POSTGRES_WORK_MEM- Per-operation memory (e.g., "64MB")FERREX_POSTGRES_MAX_CONNECTIONS- Max concurrent connections (e.g., "100")FERREX_POSTGRES_SHM_SIZE- Docker shm_size (e.g., "8g")FERREX_POSTGRES_MAINTENANCE_WORK_MEM- Maintenance operations memoryFERREX_POSTGRES_WAL_BUFFERS- Write-ahead log buffersFERREX_POSTGRES_HUGE_PAGES- Huge pages support ("on" or "off")FERREX_POSTGRES_MIN_WAL_SIZE- Minimum WAL sizeFERREX_POSTGRES_MAX_WAL_SIZE- Maximum WAL size
Example with overrides:
FERREX_POSTGRES_PRESET=medium
FERREX_POSTGRES_SHARED_BUFFERS=8GB # Override preset valueFerrex can terminate TLS directly. If you prefer a reverse proxy (nginx, Caddy, Traefik), terminate TLS there and run Ferrex over HTTP on localhost.
To enable HTTPS directly in Ferrex, set certificate and key paths:
TLS_CERT_PATH=/path/to/cert.pem
TLS_KEY_PATH=/path/to/key.pemAdvanced (optional):
TLS_MIN_VERSION– Minimum TLS version to allow. Defaults to1.3.1.3(recommended) or1.2.
TLS_CIPHER_SUITES– Comma‑separated allow‑list of TLS 1.3 cipher suites.- Example:
TLS13_AES_256_GCM_SHA384,TLS13_CHACHA20_POLY1305_SHA256
- Example:
Notes:
- Default behavior is TLS 1.3 (Ferrex Player is the primary client).
- If you set
TLS_MIN_VERSION=1.3, very old clients that only support TLS 1.2 will fail to connect — this is expected and desired for hardening. - Certificate hot‑reload is supported: when
cert.pem/key.pemcontents change, the server reloads them (checked every ~5 minutes).
- Ferrex is under active development; avoid exposing the server directly to the public Internet.
- Prefer running on an internal network, behind a reverse proxy, or via the Tailscale sidecar.
- See
.github/SECURITY.mdfor the security policy.