Skip to content

Configuration

Roombarr is configured through a single YAML file at /config/roombarr.yml. It validates the entire config at startup and refuses to start if anything is invalid.

dry_run: true
services: { ... }
schedule: "0 3 * * *"
performance: { ... }
audit: { ... }
rules: [...]

Defaults to true, making Roombarr safe to deploy out of the box. When true, Roombarr evaluates every rule and logs what it would do, but never calls Radarr or Sonarr APIs to perform actions. Set to false only after reviewing your evaluation results.

dry_run: false

The services block tells Roombarr how to connect to your *arr stack. Each service needs a base_url and an api_key.

Required: At least one of radarr or sonarr.

Optional: jellyfin and jellyseerr are enrichment services — only needed if your rules reference their fields.

services:
radarr:
base_url: http://radarr:7878 # Settings → General → API Key
api_key: your-radarr-api-key
sonarr:
base_url: http://sonarr:8989
api_key: your-sonarr-api-key
jellyfin:
base_url: http://jellyfin:8096 # Dashboard → API Keys
api_key: your-jellyfin-api-key
jellyseerr:
base_url: http://jellyseerr:5055 # Settings → General → API Key
api_key: your-jellyseerr-api-key

If Roombarr and your services are on the same Docker network, use Docker service names as the URL (e.g., http://radarr:7878). No trailing slash.

If a rule references a field from an unconfigured service, Roombarr will refuse to start and tell you exactly which service is missing.

Required. Standard 5-field cron expression (minute hour day month weekday). Evaluates in the timezone set by the TZ environment variable (defaults to UTC).

schedule: "0 3 * * *" # Daily at 3:00 AM

You can also trigger evaluations manually via the HTTP API.

Optional. Controls the maximum number of concurrent API requests to external services.

performance:
concurrency: 10 # 1–50, default: 10

Optional. Every action decision is logged to daily-rotated JSONL files in the /config volume.

audit:
retention_days: 90 # 1–3650, default: 90

Rules are the core of Roombarr. Each rule targets either radarr or sonarr, defines conditions using a composable AND/OR tree, and specifies an action.

rules:
- name: Delete fully watched old movies
target: radarr
action: delete
conditions:
operator: AND
children:
- field: jellyfin.watched_by_all
operator: equals
value: true
- field: radarr.added
operator: older_than
value: 6mo
  • name — Human-readable label for logs and audit trail.
  • targetradarr (evaluates per-movie) or sonarr (evaluates per-season).
  • actiondelete, unmonitor, or keep. See Actions below.
  • conditions — An AND/OR condition tree.
TargetEvaluatesOn delete
radarrEach movie independentlyRemoves the movie and deletes files from disk
sonarrEach season independentlyDeletes episode files for that season only

The top-level conditions is always a group with operator (AND/OR) and children.

# All children must match
conditions:
operator: AND
children:
- field: radarr.monitored
operator: equals
value: false
- field: radarr.added
operator: older_than
value: 1y
# At least one child must match
conditions:
operator: OR
children:
- field: jellyfin.watched_by_all
operator: equals
value: true
- field: radarr.added
operator: older_than
value: 2y
- field: radarr.year # Dotted field path
operator: less_than # Comparison operator
value: 2010 # Value to compare against

The is_empty and is_not_empty operators must not include a value. All other operators require one.

Children can be groups or leaves — nest to arbitrary depth for complex logic like “A AND (B OR C)“:

conditions:
operator: AND
children:
- field: radarr.monitored
operator: equals
value: false
- operator: OR
children:
- field: jellyfin.watched_by_all
operator: equals
value: true
- field: radarr.added
operator: older_than
value: 2y

A rule is skipped for an item when the enrichment data it needs is missing — Roombarr won’t act on incomplete information.

  • Missing item data — If Jellyfin has no data for a specific movie, rules referencing jellyfin.* fields are skipped for that movie only.
  • Unreachable service — If Jellyfin is down, all items have null Jellyfin data and every rule referencing Jellyfin fields is skipped for that run.
ActionDescription
deleteRemove from Radarr/Sonarr and delete files from disk
unmonitorStop monitoring for new downloads (files stay)
keepExplicitly protect this item from other rules (no-op)

When multiple rules match the same item, Roombarr uses least-destructive-wins:

keep > unmonitor > delete

This means you can write broad cleanup rules and add targeted keep rules to protect specific items — the keep rules always win. Rule order in the config file does not matter.

Roombarr reads the config once at startup. To apply changes, restart the container. For example, with Docker Compose:

Terminal window
docker compose restart roombarr

Other platforms (Unraid, TrueNAS, Portainer) have their own restart mechanisms — consult your platform’s docs.

VariableDefaultDescription
PUID1000User ID for file permissions — see Understanding PUID and PGID
PGID1000Group ID for file permissions
CONFIG_PATH/config/roombarr.ymlPath to the YAML config file
PORT3000HTTP server listen port
TZ(UTC)Timezone for cron schedule evaluation (e.g., America/New_York)
NODE_ENVproductionControls log format. Set to development for pretty-printed logs.

Roombarr validates the entire config at startup. Beyond schema validation, it checks:

  • At least one of radarr or sonarr is configured
  • Each rule’s target matches a configured service
  • Enrichment services are configured if rules reference their fields
  • Operators are compatible with the field types they’re applied to