# Sortarr Sortarr is a self-hosted Jellyfin media organizer and dashboard. It watches `/downloads`, plans safe Jellyfin-friendly moves, chooses one of four mounted media drives, exposes storage, downloads, and library state, and ships with a fully editable vanilla dashboard. The project is intentionally source-first: backend logic is plain Python, the UI is HTML/CSS/JS, and runtime behavior is configured with `.env`, TOML config files, and optional CSS overrides. ## Quick Start 1. Copy the environment template: ```bash cp .env.example .env ``` 2. Edit `.env` and set `DOWNLOADS_PATH`, `DRIVE1_PATH`, `DRIVE2_PATH`, `DRIVE3_PATH`, and `DRIVE4_PATH`. 3. Review `config/app.toml`. Keep `SORTARR_DRY_RUN=true` until the generated plans look right. 4. Start the stack: ```bash docker compose up --build ``` 5. Open `http://localhost:8088`. Production mode: ```bash docker compose -f compose.yaml -f compose.prod.yaml up -d --build ``` Optional profiles: ```bash docker compose --profile cache up -d docker compose --profile database up -d docker compose --profile tools up -d ``` ## Services - `web`: nginx serving the editable dashboard from `web/src`. - `backend`: Python API plus 24/7 worker loop. - `redis`: optional cache profile for future workflow extensions. - `postgres`: optional database profile for installations that outgrow JSON state. - `media-tools`: optional ffmpeg tools container. ## Mounted Host Paths - `/downloads`: incoming files. - `/media/drive1` through `/media/drive4`: Jellyfin media drives. - `/config`: TOML config and custom CSS. - `/logs`: rotating backend logs. - `/data`: JSON state and scan history. ## Safety Model Sortarr defaults to dry-run mode. In dry-run mode it scans, parses, chooses drives, computes destination paths, and records planned actions without moving files. When dry-run is disabled, moves use a temporary `.sorting` destination before the final rename. Existing destinations follow the configured collision rule: `keep-both`, `skip`, or `replace`. ## Permissions The default Compose file runs the backend with the container default user so a fresh checkout can create logs, state, and media folders without a bootstrap script. On a hardened media host, set ownership on the mounted paths and add a `user: "${SORTARR_UID}:${SORTARR_GID}"` line to the backend service in a local override. ## Customization Edit these files directly: - `config/app.toml`: runtime organizer rules and provider settings. - `.env`: deployment paths, ports, and intervals. - `backend/sortarr/*.py`: parsing, drive choice, scanner, API, provider integrations. - `web/src/*.html`, `*.css`, `*.js`: dashboard layout, styling, themes, routes. - `config/custom-theme.css`: host-side CSS variable overrides loaded at runtime. See `docs/configuration.md`, `docs/api.md`, and `docs/operations.md`.