For Radarr & Sonarr

The right folder, every time.

Routarr reads your libraries, enriches every title from the metadata sources you order, and decides which root folder it belongs in. You see the whole plan first, and it writes only when you say so.

GPLv3 licence · amd64 & arm64 · No telemetry

The dry-run plandry-run20 evaluated · 13 moves required · 7 already correct
The dry-run plan: six titles, the rule that decided each one, its destination, its instance and its status.
TitleVia ruleDestinationInstanceStatus
Akira (1988)#10 Japanese animation/movies to /movies/animeRadarrMove
Stop Making Sense#20 Concert films/movies to /movies/concertsRadarrMove
Cowboy Bebop#10 Japanese animation/tv to /tv/animeSonarrMove
Paddington 2#30 Family & kids/movies to /movies/kidsRadarrMove
Whiplashdefault category/moviesRadarrAlready correct
Homecoming#20 Concert films/movies/concertsRadarrAlready correct

Move moves on apply Already correct already there

The rule engine

28 conditions, your logic.

Combine conditions with ALL or ANY, add explicit exclusions, order rules by priority. Genre, language, country, certification, age and size, plus the signals only your Arr has: tags, Sonarr's series type and season count.

Japanese animation

Priority 10Films & series

routes to anime

Conditions

All (in force) Any

original_languageis one ofja

genre_containscontainsAnimation

Except when

certification_inis one ofGUTV-Y

Exclusions are why this works. "Japanese animation" would swallow My Neighbor Totoro. The deliberate exclusion of G-rated certifications hands it to kids instead, and the interface says so.

Safety

Nothing is written until six gates agree.

All six are on by default, they run in this order, and the first to object stops the rest. The first alone makes the whole application read-only.

  1. 01

    Global dry-run

    On from the first launch. Nothing is written while it is on.

    refuses
  2. 02

    Batch limit

    A ceiling on how many titles one apply can touch. A whole simulation is applied in slices of that size, and always asks first.

    refuses
  3. 03

    Reachability

    A destination that did not answer. A sleeping NAS reads like a dead disk, so this one asks.

    asks
  4. 04

    Capacity

    The plan weighed against the free space, counting only the bytes that cross a filesystem.

    asks
  5. 05

    Confirmation threshold

    Past a number you choose, a second explicit confirmation is required.

    asks
  6. 06

    Revalidation at apply time

    Checked again against the current rules. A decision they no longer justify is refused.

    refuses

refuses stops the apply asks raises a question under its own name, which you answer

Automatic application exists and is off by default. Enabled, it touches only titles with no files on disk yet.

Install

Up in one compose up.

One image carries the backend and the interface, for amd64 and arm64. Save the compose file and start it: the first run needs no configuration.

  1. 01

    mkdir -p config && sudo chown 1000:1000 config

    The container runs as uid 1000 and drops every capability, so the volume has to belong to it.

  2. 02

    docker compose up -d

  3. 03

    docker exec routarr cat /config/routarr.api_key

    Generated on first start and written beside the database. The log prints it once, the file keeps it.

  4. 04

    http://localhost:9876

    Global dry-run is already on. Nothing can be written until you turn it off.

docker-compose.yml
services:
  routarr:
    image: ghcr.io/routarr/routarr:latest
    container_name: routarr
    ports:
      - "9876:9876"
    volumes:
      - ./config:/config
    restart: unless-stopped
    stop_grace_period: 30s
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true

Keep copies of the archives in config/backups/. Routarr writes one on a schedule, a consistent copy of the database and of the routarr.key without which the stored Arr credentials cannot be recovered. Copy the config/ folder itself only with Routarr stopped.

The rest

More, on its own page.

Everything above is what Routarr does. What follows is how it does it, and it is there for whoever wants it rather than in the way of whoever does not.

How it decides