A lightweight, privacy-first management suite for qbittorrent-nox on Debian Linux — including ARM64 and proot-Termux environments.
qbit-forge wraps qbittorrent-nox with a PyQt6 desktop GUI, a native WebUI launcher,
and a package manager. Everything runs locally, offline-first, with no cloud dependency.
- Architecture
- Project Structure
- Requirements
- Quick Start
- Build
- Install
- Components
- How It Works
- Known Limitations / TODO
- Author
┌─────────────────────────────────────────┐
│ qbit-forge (GUI) │ PyQt6 — system tray app
│ Start · Stop · Restart · WebUI │
└──────────────┬──────────────────────────┘
│ subprocess + poll
▼
┌──────────────────────┐ ┌──────────────────────┐
│ qbittorrent-nox │──▶│ qb-webui │
│ (managed process) │ │ (GTK native webview)│
└──────────────────────┘ └──────────────────────┘
┌──────────────────────┐
│ qb-main │ standalone CLI — install / upgrade / clean
└──────────────────────┘
qbit-forge/
├── assets/
│ └── qbit-forge.png # Application icon
├── bin/ # Built binaries (git-ignored)
│ ├── qbit-forge # Desktop GUI binary
│ ├── qb-main # Package manager CLI
│ └── qb-webui # Native WebUI launcher
├── builder/
│ ├── build-bin.sh # Go build script (qb-main + qb-webui)
│ └── build-main.sh # PyInstaller build script
├── core/
│ ├── main.py # GUI entry point
│ ├── qbit-forge.spec # PyInstaller spec
│ └── requirements.txt # Python dependencies
├── go-src/
│ ├── qb-main/ # qb-main CLI source (Go)
│ │ ├── main.go # CLI dispatch
│ │ ├── manager.go # Install / Update / Upgrade / Clean
│ │ ├── runner.go # Privilege-aware command runner
│ │ ├── deb_install.go # .deb fallback installer
│ │ └── print.go # Colored output helpers
│ └── qb-webui/ # Native WebUI launcher source (Go)
│ ├── main.go # webview wrapper, loading screen, retry
│ └── tls.go # TLS config (-insecure flag)
├── install.sh # Symlink + desktop entry installer
├── Makefile # Build / install / clean targets
├── LICENSE # MIT
└── README.md
| Dependency | Version | Purpose |
|---|---|---|
qbittorrent-nox |
any | The managed application |
| Python | 3.10+ | GUI runtime |
| PyQt6 | 6.4+ | GUI framework |
| Tool | Version | Purpose |
|---|---|---|
| Go | 1.21+ | Build qb-main, qb-webui |
| GCC / libwebkit2gtk | — | Build qb-webui (CGO=1) |
| PyInstaller | 6.0+ | Build standalone qbit-forge GUI binary |
# qb-webui build dependency
sudo apt-get install libwebkit2gtk-4.0-dev gcc
# GUI runtime
pip install PyQt6# 1. Clone
git clone https://github.com/dev-boffin-io/qbit-forge
cd qbit-forge
# 2. Install qbittorrent-nox (if not already installed)
./bin/qb-main install
# 3. Build everything
make build
# 4. Install (symlinks + desktop entry)
make install
# 5. Launch
qbit-forgemake buildmake build-bin
# Cross-compile for ARM64
./builder/build-bin.sh --arch arm64
# Specific OS/arch
./builder/build-bin.sh --os linux --arch amd64qb-main is built with CGO=0 (fully static, cross-compile supported).
qb-webui is built with CGO=1 (requires host C compiler and libwebkit2gtk).
make build-guiThe build script creates a fresh .venv, installs dependencies, runs PyInstaller,
and cleans up. Only bin/qbit-forge remains.
pip install -r core/requirements.txt
make runmake installThis runs install.sh which:
- Symlinks
qbit-forge,qb-main,qb-webuiinto~/.local/bin/ - Copies
assets/qbit-forge.pngto~/.local/share/icons/ - Writes
~/.local/share/applications/qbit-forge.desktop - Refreshes the desktop database
To uninstall:
make uninstallA PyQt6 system tray application that manages a single qbittorrent-nox instance.
Features:
- Lives in the system tray — minimises to tray on close
- Auto-starts
qbittorrent-noxon launch - Captures the WebUI password automatically from process output
- Caches credentials so subsequent starts skip the capture step
- Auto-detects a free port starting from
8081 - Opens
qb-webui(native window) or browser fallback on ready - Start / Stop / Restart controls with confirmation dialogs
- Show Password dialog — displays username, password, and WebUI URL
State files (stored in $HOME):
| File | Purpose |
|---|---|
~/.qbit-forge-initialized |
First-run flag |
~/.qbit-forge-credentials |
Cached username:password |
~/.qbit-forge-port |
Active WebUI port |
Opens the qBittorrent WebUI in a native GTK webview window. Built with webview/webview_go.
Usage:
qb-webui [flags]
Flags:
-url string WebUI URL (e.g. http://localhost:8081)
-host string Host (default: localhost)
-port int WebUI port (default: 8080)
-scheme string http or https (default: http)
-retries int Connection retry limit (default: 15)
-width int Window width in pixels (default: 1600)
-height int Window height in pixels (default: 960)
-zoom float Page zoom level (default: 1.5)
-kiosk Fullscreen kiosk mode
-insecure Skip TLS verification
Examples:
qb-webui -url http://localhost:8081
qb-webui -url http://localhost:8081 -zoom 1.8
qb-webui -url https://myserver -insecureA Catppuccin Mocha loading screen is shown while connecting. On failure, an error card appears with a Retry button.
Handles installation, upgrade, and removal of qbittorrent-nox.
Usage:
qb-main install Install qbittorrent-nox (apt first, .deb fallback)
qb-main update Refresh apt cache
qb-main upgrade Upgrade to latest available version
qb-main clean Uninstall qbittorrent-nox + remove instance data
install strategy: tries apt-get install first; if apt is unavailable
or fails, falls back to downloading a .deb directly from ftp.debian.org.
upgrade strategy: runs apt-get install --only-upgrade; falls back to
.deb download if apt is unavailable.
clean: purges the package via apt/dpkg and removes ~/.config/qb-manager/.
On the very first launch, qbit-forge spawns qbittorrent-nox in the foreground,
reads its stdout to capture the auto-generated temporary password, saves it to
~/.qbit-forge-credentials, and marks initialization complete with
~/.qbit-forge-initialized.
Credentials are read from ~/.qbit-forge-credentials. qbittorrent-nox is
started in daemon mode (-d) with the saved port. The GUI polls the WebUI
endpoint until it responds, then opens qb-webui.
qbittorrent-nox prints the temporary WebUI password to stdout on first start.
qbit-forge reads this line with a regex, saves admin:<password> to the
credentials file, and uses it for all subsequent API calls and the Show Password
dialog.
On each start, qbit-forge scans ports from 8081 upward and picks the first
free one. The chosen port is saved to ~/.qbit-forge-port.
- Password capture relies on stdout — versions that write only to
/dev/ttyfall back toadminadmin -
qb-mainonly supports Debian/dpkg-based systems -
qb-webuikiosk mode relies on window manager co-operation - No torrent management UI (add, remove, pause individual torrents)
- GUI binary not yet signed or packaged as
.deb/ AppImage
Sumit — github.com/dev-boffin-io