# qBittorrent qBittorrent is the torrent download client for the *arr stack on Dankserver. It receives download requests from Sonarr, Radarr, Lidarr, and Readarr via category tagging. **Host:** Dankserver — **Hostname:** `qbittorrent.dankserver.local` — **Docs:** https://www.qbittorrent.org ## Facts | Item | Value | |------|-------| | Image | `lscr.io/linuxserver/qbittorrent:latest` | | Port | 8080 (host) → 8080 (container) | | Min RAM | 512 MB | | Auth | Web UI username/password; LAN mode available | ## Configuration 1. Keep Web UI authentication ON (LAN bypass not needed — the arr apps authenticate with the API) and give them a permanent password. 2. Create download categories per app (`radarr`, `sonarr`, `lidarr`, `readarr`): the arr download clients route category-per-app, and Prowlarr feeds hand grabs to each app's own client. 3. Set max active downloads: Settings → Downloads (recommended: 5 global, 3 per category). ## Persistent WebUI credentials (verified 2026-08-30) qBittorrent 5 mints a **new temporary password at every start** unless a password is stored in `qBittorrent.conf`. That rotation silently breaks every arr download client after each reboot. The Web-API has no password endpoint any more (`/api/v2/app/setPassword` was removed), and the linuxserver image has no `WEBUI_AUTH` handling — so persistence must be written to the conf directly, in qb's own `salt:hash` format (`src/base/utils/password.cpp`: PBKDF2-HMAC-SHA512, 100 000 iterations, 16-byte salt = 4×uint32, then `base64(salt) + ":" + base64(hash)` as the raw value): ```python import base64, hashlib, os salt = os.urandom(16) h = hashlib.pbkdf2_hmac("sha512", password.encode(), salt, 100000, 64) val = (base64.b64encode(salt) + b":" + base64.b64encode(h)).decode() # with the container STOPPED, in [Preferences]: # WebUI\Username=admin # WebUI\Password_PBKDF2= ``` Then `podman start qbittorrent` and confirm login survives a `podman restart` — the temp-password rotation stops the moment stored credentials verify. The chosen value lives host-local in `/home/dank/.qbpass` (mode 600, owner `dank`) — never in git; every arr download client and `prowlarr.md` reference it. (The classic `@ByteArray(salt+hash)` form is WRONG for qb5: login 401s on it; verify() base64-decodes the two halves separately.) ## Docker Compose ```yaml qbittorrent: image: lscr.io/linuxserver/qbittorrent:latest container_name: qbittorrent restart: unless-stopped environment: - PUID=1000 - PGID=1000 - TZ=America/New_York - UMASK_SET=022 volumes: - /opt/qbittorrent/config:/config - /mnt/media/downloads:/downloads - /mnt/media/downloads/incomplete:/downloads/incomplete ports: - "8080:8080" networks: [appnet] ``` ## Gotchas (verified live) - Temporary-password rotation on every boot is the default state of an untouched qb5 — see the persistence recipe above; without it, all arr download clients silently fail queue adds ("Couldn't add release … to download queue" in the arr logs) after any restart. - API login from `curl` needs a `Referer: http://:/` header (CSRF protection) or POSTs get rejected even with a valid SID. - Ensure umask is set to `022` so downloaded files are readable by arr apps. - Monitor bandwidth limits to avoid saturating the network. ## See Also - [[ARR-Stack]] — full *arr stack documentation