Docker
Docker is the recommended way to run Praxrr alongside Radarr, Sonarr, and Lidarr. The repository ships production and development compose files you can adapt to your stack.
Production compose
Section titled “Production compose”The root compose.yml maps host port 6969 to container port 6868 and
mounts ./config to /config:
docker compose up -dKey environment variables in the sample file:
| Variable | Example | Notes |
|---|---|---|
APP_BASE_PATH |
/config |
Implicit via volume mount |
PRAXRR_DEFAULT_DB_URL |
GitHub URL or empty | Auto-link on startup |
ARR_CREDENTIAL_MASTER_KEY |
REDACTED |
Required for Arr API keys |
RADARR_INSTANCE_URL_1 |
http://radarr:7878 |
Docker network hostname |
Pass secrets through a .env file or your orchestrator. Do not commit real API
keys or master keys.
Development compose
Section titled “Development compose”Build from source with live rebuild watches:
docker compose -f compose.dev.yml --profile dev up --build --watchThe dev profile bind-mounts optional local packages/praxrr-db and
packages/praxrr-schema paths for PCD and schema development.
Start local Arr containers for integration testing:
docker compose -f compose.dev.yml --profile arr up -d lidarr radarr sonarrOr run the full dev stack (Praxrr, parser, Arr, and TSDProxy):
docker compose -f compose.dev.yml --profile dev --profile arr up --build --watchTailscale access (dev compose)
Section titled “Tailscale access (dev compose)”The dev compose file does not publish host ports. Instead,
TSDProxy exposes services over
HTTPS on your Tailscale tailnet. All hostnames are prefixed with praxrr to
avoid collisions.
First-time setup
Section titled “First-time setup”mkdir -p .tsdproxy/config .tsdproxy/datacp docker/tsdproxy.yaml.example .tsdproxy/config/tsdproxy.yamlOptionally set tailscale.providers.praxrr.authKey in .tsdproxy/config/tsdproxy.yaml
for unattended (headless) Tailscale authentication. Otherwise, authenticate
interactively through the TSDProxy dashboard.
Dev compose labels set tsdproxy.proxyprovider: praxrr. That pin is required when another
TSDProxy (for example rfmedia-apps tsdproxy-rfapps) is also watching the same Docker socket;
without it both daemons register the same hostname and Tailscale creates git-1 / plex-1
duplicates.
Tailscale hostnames
Section titled “Tailscale hostnames”Replace <tailnet> with your tailnet name (for example my-tailnet):
| Service | Tailscale name | URL |
|---|---|---|
| Praxrr UI | praxrr-dev |
https://praxrr-dev.<tailnet>.ts.net |
| TSDProxy dashboard | praxrr-tsdproxy |
https://praxrr-tsdproxy.<tailnet>.ts.net |
| Radarr | praxrr-radarr |
https://praxrr-radarr.<tailnet>.ts.net |
| Sonarr | praxrr-sonarr |
https://praxrr-sonarr.<tailnet>.ts.net |
| Lidarr | praxrr-lidarr |
https://praxrr-lidarr.<tailnet>.ts.net |
Authenticating proxies
Section titled “Authenticating proxies”After starting the stack:
- Open
https://praxrr-tsdproxy.<tailnet>.ts.netfrom a device on your tailnet. - Sign in to Tailscale if prompted.
- Approve each proxy card for the services you want to expose.
The parser service (parser-dev) remains internal-only. Praxrr reaches it over
the Docker network at parser-dev:5000; it is not proxied to Tailscale.
Volumes
Section titled “Volumes”Mount a persistent volume at /config (or set APP_BASE_PATH accordingly).
Praxrr stores:
| Path under base | Contents |
|---|---|
data/praxrr.db |
App SQLite database |
data/databases/ |
Cloned PCD repositories |
logs/ |
Application logs |
backups/ |
Backup archives |
Use matching PUID, PGID, and UMASK values so the container user can write
to the mounted directory.
Networking
Section titled “Networking”- Internal API URL: Set instance URLs to Docker service names (for example
http://praxrr-radarr:7878) so Praxrr reaches Arr over the compose network. - External URL: Set
RADARR_INSTANCE_EXTERNAL_URL_1(or the Sonarr/Lidarr equivalents) when browser links should use a public hostname or reverse-proxy path. In dev compose, uncomment the Tailscale URL hints incompose.dev.yml(for examplehttps://praxrr-radarr.<your-tailnet>.ts.net). API traffic still uses the canonical URL field. - Parser: When enabled, set
PARSER_HOSTto the parser service name (parserin production,parser-devin dev compose) andPARSER_PORT=5000.
Behind a reverse proxy
Section titled “Behind a reverse proxy”When a reverse proxy fronts Praxrr, set TRUSTED_PROXY to the proxy’s address
as Praxrr sees it so the real forwarded client IP is honored (and spoofed ones
from other peers are ignored). On a shared compose network that is the proxy
container’s subnet; use loopback if the proxy runs on the same host.
services: praxrr: image: ghcr.io/yandy-r/praxrr:latest environment: - AUTH=local - TRUSTED_PROXY=172.18.0.0/16 # the compose network the proxy sits onUnder AUTH=local, do not leave TRUSTED_PROXY unset behind a proxy.
With it unset, Praxrr grades every request by the direct peer — the proxy
container’s own IP. Because compose proxies sit on a private subnet
(10.x, 172.16-31.x, 192.168.x), that IP is itself “local”, so every
proxied request (including remote clients) is treated as local and skips
authentication. Setting TRUSTED_PROXY to the proxy makes Praxrr grade the real
forwarded client instead: remote clients then authenticate while LAN clients
keep the intended AUTH=local bypass. The proxy must also overwrite/strip
client-supplied forwarded headers (e.g. nginx $proxy_add_x_forwarded_for).
Praxrr’s Security Posture flags the unset case as the proxy_trust_missing
advisory. See the Trusted proxy guide for
the full grammar and failure behavior.
Parser opt-in
Section titled “Parser opt-in”Custom format testing and quality profile simulation require the optional
praxrr-parser container. Minimal production stacks can omit it:
services: praxrr: image: ghcr.io/yandy-r/praxrr:develop ports: - '6868:6868' volumes: - ./config:/config environment: - ARR_CREDENTIAL_MASTER_KEY=REDACTED - ARR_CREDENTIAL_MASTER_KEY_VERSION=v1Without a parser, linking and syncing continue to work.
Pull on startup
Section titled “Pull on startup”Optionally import sync selections from Arr when Praxrr starts:
PULL_ON_START=truePULL_ON_START_MAX_CONCURRENCY=2PULL_ON_START_TIMEOUT_MS=30000This runs as a non-blocking background job and reconstructs which profiles are already present on each instance.
Validate instances at startup
Section titled “Validate instances at startup”Set PRAXRR_VALIDATE_INSTANCES=true to ping each env-managed instance during
startup. Useful in CI or after rotating API keys.
Next steps
Section titled “Next steps”- Installation — binary and source paths
- Configuration — full environment reference
- Connecting Arr Instances — URL modes