All apps · 0 apps
torbox-client
Docker app from devblaze's Repository
Overview
Readme
View on GitHubtorbox-client
Use TorBox as a download client for Sonarr and Radarr — the same way rdt-client lets you use Real-Debrid.
It pretends to be qBittorrent: your *arr apps send releases to it exactly as they would to a normal torrent client. Behind the scenes it hands each release to TorBox, waits for TorBox to download it in the cloud, then pulls the finished files down to your downloads share so Sonarr/Radarr import them normally.
Sonarr/Radarr ──(qBittorrent API)──▶ torbox-client ──(TorBox API)──▶ TorBox cloud
▲ │ │
└───────── imports from ◀── /downloads ◀──── pulls finished files ──┘
How it works
- Sonarr/Radarr grab a release and push the magnet/
.torrentto this service (qBittorrenttorrents/add). - It computes the real infohash (so *arr can track it) and sends it to TorBox.
- A background worker polls TorBox for progress. Progress is reported to *arr but capped below 100% until files are actually on local disk — so nothing imports early.
- When TorBox finishes, the worker downloads each file to
/downloads/<category>/…. - Once every file is local, the torrent reports completed and Sonarr/Radarr import it (hardlink/move into your library).
- After import, *arr removes it; the service deletes the local files and (optionally) the TorBox cloud torrent.
Prerequisites
- A TorBox account + API key — from https://torbox.app/settings (API section).
- Sonarr and/or Radarr.
- The single most important rule: Sonarr/Radarr and this container must see the completed files at the same path. On Unraid that means mounting the same share (e.g.
/mnt/user/data) at the same container path everywhere. This is what makes hardlink imports work.
Install
Option A — Unraid (recommended)
The image is published to GHCR and there's a ready-made Unraid template.
Note: The Template dropdown on the Add Container page only lists templates that already exist on your server — you can't paste a URL into it. Use one of the two methods below to make the template appear there, or just fill in the fields by hand.
Method 1 — install the template from URL (via SSH), then pick it from the dropdown:
- SSH into your Unraid server (or use the web terminal) and run:
wget -O "/boot/config/plugins/dockerMan/templates-user/my-torbox-client.xml" \ https://raw.githubusercontent.com/devblaze/torbox-client/main/templates/torbox-client.xml - Unraid → Docker tab → Add Container.
- In the Template dropdown, under User templates, choose torbox-client. All fields pre-fill.
- Adjust the values (see below), then Apply. The container starts on port 8080.
Method 2 — create the container manually:
- Unraid → Docker tab → Add Container (leave Template on Select a template).
- Set:
- Repository:
ghcr.io/devblaze/torbox-client:latest - Network Type:
Bridge - Port: add
8080→8080(tcp) - Path:
/downloads→ your downloads share, e.g./mnt/user/data/downloads - Path:
/data→/mnt/user/appdata/torbox-client - Variables (Add another Path, Port, Variable...):
TORBOX_API_KEY,QBIT_USER,QBIT_PASS, and optionallyPUID=99,PGID=100.
- Repository:
- Apply.
Values to set either way:
- TORBOX_API_KEY — your key from torbox.app/settings.
- QBIT_USER / QBIT_PASS — leave
admin/adminadminor change them (you'll type these into Sonarr/Radarr). - Downloads — set this to the same share your Sonarr/Radarr use, e.g.
/mnt/user/data/downloads→/downloads. - Appdata (state) —
/mnt/user/appdata/torbox-client→/data. - PUID/PGID — leave
99/100(Unraid defaults).
Option B — docker compose (any Docker host)
git clone https://github.com/devblaze/torbox-client.git
cd torbox-client
cp .env.example .env # set TORBOX_API_KEY (and QBIT_USER/QBIT_PASS)
# edit docker-compose.yml: point the /downloads volume at the SAME host dir
# your Sonarr/Radarr use, and set PUID/PGID if needed.
docker compose up -d
docker compose logs -f # should log: "TorBox API key validated"
Option C — build locally
docker build -t torbox-client .
docker run -d --name torbox-client -p 8080:8080 \
-e TORBOX_API_KEY=xxxx -e PUID=99 -e PGID=100 \
-v /mnt/user/data/downloads:/downloads \
-v /mnt/user/appdata/torbox-client:/data \
torbox-client
Verify it's up: curl http://<host>:8080/health → {"status":"ok"}.
Connecting Sonarr and Radarr
Do this in each app (Sonarr and Radarr). The only differences are the recommended category name.
1. Add the download client
Settings → Download Clients → ➕ → qBittorrent
| Field | Value |
|---|---|
| Name | TorBox |
| Host | the container/host running torbox-client. On Unraid or same Docker host, use the host's LAN IP (e.g. 192.168.1.10) or the container name if on the same custom Docker network. |
| Port | 8080 |
| Username | admin (or your QBIT_USER) |
| Password | adminadmin (or your QBIT_PASS) |
| Category | Sonarr → tv-sonarr • Radarr → radarr |
| Use SSL | Off |
Click Test (should go green) → Save.
2. Completed Download Handling
Settings → Download Clients (bottom of page): make sure Completed Download Handling → Enable is on (it is by default). That's what triggers Sonarr/Radarr to import from /downloads once a torrent reports completed.
3. Path matching (the thing that trips everyone up)
Sonarr/Radarr import by looking at the path the download client reports. This container reports /<downloads>/<category>/….
- If Sonarr/Radarr mount the same share at the same path as this container (e.g. everything uses
/dataor everything uses/downloads) → nothing to do. ✅ - If their internal path differs (say Sonarr sees
/data/downloadsbut this container writes to/downloads), you have two options:- Set
SAVE_PATH=/data/downloadson this container so it reports the path Sonarr expects, or - Add a Remote Path Mapping in Sonarr/Radarr (Settings → Download Clients → Remote Path Mappings): Host = the client Host you entered, Remote Path =
/downloads/, Local Path =/data/downloads/.
- Set
Recommended clean setup (mirrors TRaSH guides): mount your one media share at /data in Sonarr, Radarr and this container, use categories tv-sonarr / radarr, and point the Downloads path here at /data/downloads.
4. Test the whole flow
Search for an episode/movie and hit download. In the *arr Activity/Queue you'll see it progress: it climbs while TorBox downloads in the cloud, sits near ~90% while the files are pulled locally, then flips to completed and imports into your library.
Web UI
Open http://<host>:8080/ in a browser for a small dashboard. It refreshes automatically every few seconds and has three tabs:
- Activity — everything currently tracked, with separate progress bars for the cloud phase (TorBox downloading) and the local pull to
/downloads, plus speeds, sizes and errors. - History — a persistent event log of what happened: Added (sent to TorBox), Downloaded (files landed in
/downloads), Transferred (imported and removed by Sonarr/Radarr), and any Errors. Kept in SQLite (last 1000 events), so it survives restarts and shows items after the *arr apps delete them. - Logs — a live debug log (filterable by level) capturing the worker, TorBox API calls, and every request Sonarr/Radarr make. In-memory, last 2000 lines;
docker logsstill honoursLOG_LEVEL.
Log in with the same QBIT_USER / QBIT_PASS credentials Sonarr/Radarr use. Sessions are in-memory, so you'll be asked to sign in again after the container restarts.
Configuration reference
All configuration is via environment variables (see .env.example):
| Variable | Default | Description |
|---|---|---|
TORBOX_API_KEY |
— | Required. Your TorBox API key. |
QBIT_USER / QBIT_PASS |
admin / adminadmin |
Credentials Sonarr/Radarr log in with. |
DOWNLOAD_DIR |
/downloads |
Where this container writes finished files. |
SAVE_PATH |
= DOWNLOAD_DIR |
Path reported to *arr (set only if their mount path differs). |
PUID / PGID |
1000 / 1000 |
File ownership. Use 99 / 100 on Unraid. |
UMASK |
022 |
Umask for created files. |
POLL_INTERVAL |
15 |
Seconds between TorBox status polls. |
MAX_PARALLEL_DOWNLOADS |
4 |
Concurrent file downloads from the TorBox CDN. |
MAX_PARALLEL_TORRENTS |
2 |
Torrents pulled locally at the same time (0 = unlimited). |
MAX_DOWNLOAD_SPEED |
0 |
Aggregate download cap in MiB/s across all files (0 = unlimited). |
STALL_TIMEOUT |
90 |
Seconds without data before a stalled stream is retried with a fresh link. |
DOWNLOAD_RETRIES |
4 |
Attempts per file; each retry resumes from the bytes already on disk. |
TORBOX_CLEANUP_HOURS |
24 |
Delete the TorBox cloud copy this long after the local download completes, freeing your TorBox active-torrent slots (local files kept; 0 = never). |
DELETE_FROM_TORBOX_ON_REMOVE |
true |
Delete the cloud torrent when *arr removes the download. |
TORBOX_SEED |
1 |
TorBox seeding: 1=auto, 2=always, 3=never. |
LOG_LEVEL |
INFO |
DEBUG for verbose logging. |
Notes & limitations
- Torrents only. Usenet (SABnzbd emulation) is not implemented.
- Imports fail with "file not found"? Your paths don't match — see Path matching above.
- State is kept in SQLite at
/data/state.db; keep that volume to survive restarts.
Development
pip install -r requirements.txt
TORBOX_API_KEY=... DOWNLOAD_DIR=./dl DATA_DIR=./data \
uvicorn app.main:app --reload --port 8080
Run the tests:
pip install -r requirements-dev.txt
pytest
CI runs the suite on every push and pull request; the Docker image only publishes after tests pass.
Layout:
app/
main.py FastAPI app + lifespan wiring, request tracing, /health
config.py env-based settings
qbit_api.py qBittorrent Web API v2 emulation (talks to Sonarr/Radarr)
torbox_client.py async TorBox v1 API client
worker.py poll TorBox + download finished files locally
store.py SQLite state
bencode.py infohash computation (magnet + .torrent)
webui.py dashboard endpoints (serves /, state/history/logs JSON)
logbuffer.py in-memory ring buffer + secret redaction for the Logs tab
static/index.html the dashboard page (vanilla HTML/JS, no build step)
tests/ pytest suite (bencode, config, store, worker, qbit_api, logbuffer)
docker-entrypoint.sh PUID/PGID privilege drop
templates/torbox-client.xml Unraid Community Applications template
.github/workflows/ tests, then builds & publishes the image to GHCR
Install torbox-client on Unraid in a few clicks.
Find torbox-client in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/devblaze/torbox-client:latestRuntime arguments
- Web UI
http://[IP]:[PORT:8080]/- Network
bridge- Shell
sh- Privileged
- false
Template configuration
Port Sonarr/Radarr connect to (the emulated qBittorrent API).
- Target
- 8080
- Default
- 8080
- Value
- 8080
MUST be the same downloads share (at the same path) that Sonarr/Radarr use, so imports work.
- Target
- /downloads
- Default
- /mnt/user/data/downloads
- Value
- /mnt/user/data/downloads
Persistent SQLite state.
- Target
- /data
- Default
- /mnt/user/appdata/torbox-client
- Value
- /mnt/user/appdata/torbox-client
Your TorBox API key from https://torbox.app/settings
Username you enter in Sonarr/Radarr.
- Default
- admin
- Value
- admin
Password you enter in Sonarr/Radarr.
- Default
- adminadmin
- Value
- adminadmin
User ID for file ownership (Unraid default: 99 = nobody).
- Default
- 99
- Value
- 99
Group ID for file ownership (Unraid default: 100 = users).
- Default
- 100
- Value
- 100
Umask for created files.
- Default
- 022
- Value
- 022
Only set this if Sonarr/Radarr see the downloads at a DIFFERENT internal path than this container (e.g. /data/downloads). Otherwise leave blank.
Seconds between TorBox status polls.
- Default
- 15
- Value
- 15
Concurrent file downloads from the TorBox CDN.
- Default
- 4
- Value
- 4
Torrents pulled locally at the same time (0 = unlimited).
- Default
- 2
- Value
- 2
Aggregate download speed cap in MiB/s across all files (0 = unlimited).
- Default
- 0
- Value
- 0
Delete the TorBox cloud copy this long after the local download completes (0 = never). Frees your TorBox active-torrent slots; local files are kept.
- Default
- 24
- Value
- 24