Skip to content

qbit_manage

qbit_manage GitHub · Wiki · TRaSH: 3rd-party tools


qbit_manage is a housekeeping tool for qBittorrent. It runs on a schedule, talks to qBittorrent's Web API and can:

  • set categories from the save path, or from the tracker a torrent came from,
  • tag torrents by tracker, and tag ones with tracker errors, stalled downloads, or no hardlinks left in the library,
  • apply share limits (ratio / seed time) per group of tags or categories,
  • remove unregistered torrents and orphaned files (both off here),
  • and, since v4, give you a web UI to edit the config and run commands on demand.

Container

From the stack compose:

  qbit_manage:
    container_name: qbit_manage
    image: ghcr.io/stuffanthings/qbit_manage:v4.14.0 # pinned; v4 changed ports and config schema
    volumes:
      - ${APPDATA_PATH}/qbit_manage/:/config:rw
      - ${MEDIA_DATA}:/data:rw
      - ${APPDATA_PATH}/qbittorrent/config:/qbittorrent/:ro
    ports:
      - "8084:8080"  # Web API/UI - host port 8084 because qBittorrent's web UI already has 8080
    environment:
      # Web API Configuration
      - QBT_WEB_SERVER=true     # enable the web API and web UI
      - QBT_PORT=8080           # web port inside the container (upstream default: 8181)
      # Scheduler Configuration
      - QBT_RUN=false           # false = keep running on the schedule
      - QBT_SCHEDULE=2          # minutes between runs
      - QBT_CONFIG_DIR=/config
      - QBT_LOGFILE=qbit_manage.log
      # Command Flags (all false here: the commands come from config.yml)
      - QBT_RECHECK=false
      - QBT_CAT_UPDATE=false
      - QBT_TAG_UPDATE=false
      - QBT_REM_UNREGISTERED=false
      - QBT_REM_ORPHANED=false
      - QBT_TAG_TRACKER_ERROR=false
      - QBT_TAG_NOHARDLINKS=false
      - QBT_SHARE_LIMITS=false
      - QBT_SKIP_CLEANUP=false
      - QBT_DRY_RUN=false
      - QBT_STARTUP_DELAY=0
      - QBT_SKIP_QB_VERSION_CHECK=false
      - QBT_DEBUG=false
      - QBT_TRACE=false
      # Logging Configuration
      - QBT_LOG_LEVEL=INFO
      - QBT_LOG_SIZE=10
      - QBT_LOG_COUNT=5
      - QBT_DIVIDER==
      - QBT_WIDTH=100
    restart: on-failure:2
    labels:
      - autoheal=true
    # No official healthcheck - its own web UI (enabled via QBT_WEB_SERVER above) responds on QBT_PORT
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
Mount Why
/config config.yml (what to do), qbm_settings.yml (web UI security settings) and logs.
/data Same path as qBittorrent's /data, so the paths qBittorrent reports exist here too. Needed for the no-hardlinks check and orphaned-file cleanup.
/qbittorrent (read-only) qBittorrent's config folder, so qbit_manage can read the .torrent files in BT_backup (used when it saves torrents to the recycle bin).

Not behind the VPN

qbit_manage only talks to qBittorrent's API, so it doesn't need to be inside Gluetun. It reaches qBittorrent at http://gluetun:8080, because that's where qBittorrent's API lives (qBittorrent shares Gluetun's network stack).

config.yml: the parts that matter

Copy config.yml.sample (created in /config on first start) to config.yml. Sanitized outline of mine:

config.yml (excerpt)
commands:              # overrides the QBT_* command flags above
  cat_update: true
  tag_update: true
  tag_tracker_error: true
  rem_unregistered: false
  rem_orphaned: false
  tag_nohardlinks: false
  share_limits: false
  recheck: false
  dry_run: false

qbt:
  host: http://gluetun:8080
  user: <YOUR_USER>
  pass: <YOUR_PASSWORD>

settings:
  force_auto_tmm: true                 # turn on Automatic Torrent Management for every torrent
  tracker_error_tag: issue
  tag_stalled_torrents: true           # stalledDL tag on stuck downloads
  disable_qbt_default_share_limits: true
  cat_filter_completed: true           # only re-categorise finished torrents

directory:
  root_dir: /data/torrents/complete    # must be the same path qBittorrent uses

cat:                                   # every save path in qBittorrent must be listed
  movies: /data/torrents/complete/movies
  tv: /data/torrents/complete/tv
  Uncategorized:
    - /data/torrents/complete

tracker:                               # keyword from the tracker URL -> tag (+ optional category)
  tracker-a.example:
    tag: TrackerA
    cat: movies
  tracker-b.example:
    tag: TrackerB
  other:
    tag: other

recyclebin:
  enabled: false

How it fits together:

  • commands: wins. If config.yml has a commands: section, qbit_manage uses it and ignores the QBT_* command flags in the environment. That's why every flag in the compose is false: the real choices are in the config file, where the web UI can change them.
  • Tracker → category. A cat: on a tracker entry takes priority over the save-path mapping in cat:. Together with force_auto_tmm: true, qBittorrent then moves the torrent to that category's save path. That gives per-tracker folders without any scripting.
  • Every save path must be in cat:. If qBittorrent has a save path that isn't listed, qbit_manage logs errors. Use Uncategorized for paths that should stay without a category.
  • other: under tracker: gives every unmatched tracker one shared tag, instead of an auto-created tag per tracker domain.
  • Destructive commands are off. rem_unregistered, rem_orphaned and share_limits delete or pause things. Turn them on one at a time, with dry_run: true first, and read the log.

Web UI and authentication

The web UI is at http://<YOUR_SERVER_IP>:8084. It's a visual editor for config.yml plus a "run now" button. It can't change environment variables.

Turn authentication on

qbit_manage's web UI defaults to no authentication, and it shows and edits your config, including the qBittorrent password. In the web UI's Security section, pick Basic authentication (username + password) and generate an API key for scripts (sent as an X-API-Key header). /api/health and /api/version stay public, which is fine for healthchecks. If you lock yourself out, set authentication.method: none in qbm_settings.yml and restart.

Gotchas

  • Pin the version. v4 changed the default web port (8080 → 8181) and reworked the config schema. A floating latest can jump a major version and break QBT_* parsing. Upgrade on purpose and read the v4 migration guide.
  • Port numbers. qbit_manage listens on 8080 inside its container (set by QBT_PORT) and is published as 8084, because qBittorrent's web UI already uses 8080 on the host. The healthcheck uses the inside port.
  • Restart policy vs. autoheal. restart: on-failure:2 only covers crashes (non-zero exit, at most twice). A container that hangs but keeps running is what the autoheal=true label is for. The catch: after a long docker pause (a nightly SnapRAID sync, for example) autoheal sees it unhealthy and restarts it, and Docker has to kill it after the 10 s stop timeout. See Autoheal.

Sources & further reading