FigJam Diagram: qBittorrent — VPN Torrent Client (expires 2026-04-13)
qBittorrent is the download client in the media stack. All BitTorrent traffic is routed through an OpenVPN tunnel to the RapidSeedbox, enforced by a gluetun sidecar with kill switch. Radarr and Sonarr communicate with qBittorrent's WebUI API over the cluster network (bypassing the VPN).
medialinuxserver/qbittorrent:5.0.3 + ghcr.io/qdm12/gluetun:v3.40.0qBittorrent is not exposed publicly — internal LAN access only.
| Resource | Kind | Details |
|---|---|---|
qbittorrent-config |
PVC (Longhorn) | 2Gi — qBittorrent config |
qbittorrent-nfs-pvc |
PVC (NFS) | Downloads directory on NAS |
qbittorrent-vpn-config |
ConfigMap | OpenVPN client config (client.ovpn) — non-sensitive (CA cert + server only) |
qbittorrent |
Deployment | 1 replica, Recreate strategy |
qbittorrent |
Service | :8080 (WebUI for arr clients) |
qbittorrent-proxy |
Service | :8888 (gluetun HTTP proxy for Prowlarr) |
qbittorrent |
IngressRoute | Internal only — qbt.k3s.internal.strommen.systems |
qbittorrent-tls |
Certificate | Let's Encrypt, qbt.k3s.internal.strommen.systems |
Never commit these to git. Create out-of-band:
kubectl create secret generic qbittorrent-vpn -n media \
--from-literal=vpn-username=<username> \
--from-literal=vpn-password=<password>
| Key | Purpose |
|---|---|
vpn-username |
RapidSeedbox OpenVPN PAM username |
vpn-password |
RapidSeedbox OpenVPN PAM password |
| Setting | Value |
|---|---|
| Image | ghcr.io/qdm12/gluetun:v3.40.0 |
| VPN provider | custom (OpenVPN) |
| Seedbox endpoint | 45.128.27.65:1194/UDP |
| VPN fixed IP | 10.10.10.2 (via seedbox CCD) |
| Inbound torrent port | 6881 (DNAT'd from seedbox) |
| HTTP proxy | :8888 (for Prowlarr indexer routing) |
| Kill switch bypass CIDRs | 10.42.0.0/16, 10.43.0.0/16, 192.168.0.0/16 |
| DNS | 8.8.8.8 (plaintext, DoT disabled) |
NET_ADMIN capability |
required (TUN device) |
| Setting | Value |
|---|---|
| Image | linuxserver/qbittorrent:5.0.3 |
| PUID | 10012 (svc-rclone — see note below) |
| PGID | 10000 (media-services group) |
| WebUI port | 8080 |
| BitTorrent port | 6881 TCP+UDP |
| CPU request/limit | 200m / 2 |
| Memory request/limit | 256Mi / 1Gi |
TODO: UID isolation — qBittorrent currently runs as
svc-rclone(UID 10012), which has broad NAS access. Create a dedicatedsvc-qbittorrent(UID 10019) on the NAS scoped todownloads/only, then updatePUIDin the manifest.
Runs sysctl -w net.ipv6.conf.all.disable_ipv6=1 before pod start. Required because the seedbox VPN is IPv4-only and IPv6 leaks would bypass the kill switch.
| Container Path | NAS Subpath | Purpose |
|---|---|---|
/downloads |
downloads/ |
Root downloads directory (full tree) |
Radarr/Sonarr are configured with remote path mappings:
/downloads/movies → Radarr category/downloads/tv → Sonarr categoryqbt.k3s.internal.strommen.systems — not exposed publiclyauthentik-forward-auth from public-ingress namespace (Authentik SSO)qbittorrent-tls Certificate (Let's Encrypt, internal subdomain)No Prometheus exporter currently active. exportarr does not support qBittorrent.
TODO: Add esanchezm/prometheus-qbittorrent-exporter sidecar on port 9803. Prerequisites:
webui-password key to qbittorrent-vpn secretqbittorrent.yaml| Service | Role |
|---|---|
| Prowlarr | Uses qbittorrent-proxy:8888 for indexer routing |
| Radarr | Sends download jobs to qBittorrent WebUI API |
| Sonarr | Sends download jobs to qBittorrent WebUI API |
| Storage Architecture | NFS PV layout and NAS service accounts |
kubernetes/apps/media/qbittorrent.yaml