qBittorrent¶
qBittorrent is an open-source BitTorrent client available at qbittorrent.hdhomelab.com. All traffic is routed through an AirVPN WireGuard tunnel via the Gluetun sidecar. A Mousehole sidecar keeps the VPN IP registered on MyAnonamouse. qui provides a modern web UI for managing qBittorrent with OIDC SSO.
Deployment¶
qBittorrent runs in Kubernetes (media namespace) as a single-replica Deployment with three sidecars: Gluetun (VPN gateway), Mousehole (MAM IP updater), and qui (modern web UI). All containers share the pod network, so all traffic exits through the VPN tunnel.
graph LR
User -->|HTTPS| Gateway[Cilium Gateway]
Gateway --> qui[qui :7476]
Gateway --> Mousehole[Mousehole :5010]
Gateway --> qBittorrent[qBittorrent :8080]
qui -->|localhost:8080| qBittorrent
qBittorrent -->|pod network| Gluetun[Gluetun VPN]
Mousehole -->|pod network| Gluetun
Gluetun -->|WireGuard| AirVPN[AirVPN]
qBittorrent --> Media[(NAS Media)]
Vault -->|ExternalSecret| GluetunSecret[K8s Secret]
GluetunSecret -->|env vars| Gluetun
Vault -->|ExternalSecret| QuiSecret[K8s Secret]
QuiSecret -->|env vars| qui
-
URL
-
Namespace
media -
VPN
AirVPN via WireGuard (Gluetun sidecar)
-
Image
lscr.io/linuxserver/qbittorrent -
Config
flux/apps/noah/media/qbittorrent/ -
Storage
NFS PVC for config + NAS media share for downloads
-
qui URL
-
qui Database
PostgreSQL at
192.168.68.4:5432/qui
Secrets¶
| Vault path | Key | Used as |
|---|---|---|
gluetun |
WIREGUARD_PRIVATE_KEY |
WireGuard private key |
gluetun |
WIREGUARD_PUBLIC_KEY |
WireGuard public key |
gluetun |
WIREGUARD_PRESHARED_KEY |
WireGuard preshared key |
gluetun |
WIREGUARD_ADDRESSES |
WireGuard tunnel address |
gluetun |
FIREWALL_VPN_INPUT_PORTS |
Port-forwarded torrent port |
gluetun |
SERVER_COUNTRIES |
AirVPN server country filter |
gluetun |
SERVER_CITIES |
AirVPN server city filter |
| Vault path | Key | Used as |
|---|---|---|
psql/qui |
username |
Postgres username |
psql/qui |
password |
Postgres password |
qui/oidc |
client-id |
Authentik OIDC client ID |
qui/oidc |
client-secret |
Authentik OIDC client secret |
qui/session |
secret |
Session encryption key |
VPN (Gluetun)¶
Gluetun runs as the first container in the pod and owns the network namespace. qBittorrent and Mousehole bind to this shared network, meaning they have no direct internet access — all traffic is VPN-only.
| Setting | Value |
|---|---|
VPN_SERVICE_PROVIDER |
airvpn |
VPN_TYPE |
wireguard |
FIREWALL_INPUT_PORTS |
8080,5010,7476 — qBittorrent UI + Mousehole UI + qui UI |
FIREWALL_OUTBOUND_SUBNETS |
Cluster pod/service CIDRs (for in-cluster API calls) |
FIREWALL_VPN_INPUT_PORTS |
Port-forwarded torrent port (from Vault) |
Port forwarding
AirVPN provides a forwarded port for seeding. The value is stored in Vault and injected as FIREWALL_VPN_INPUT_PORTS. Set the same port in qBittorrent under Settings → Connection → Listening Port.
Why FIREWALL_INPUT_PORTS?
All containers in the pod share Gluetun's network namespace. Gluetun blocks all inbound traffic on the pod's cluster-facing interface (eth0) by default. FIREWALL_INPUT_PORTS whitelists specific ports so Kubernetes Services can route cluster traffic to them — without this, the ClusterIP services for qBittorrent and Mousehole would be unreachable despite the containers listening on those ports.
Mousehole¶
Mousehole is a sidecar that watches the pod's public IP and automatically updates the registered IP on MyAnonamouse (MAM) when it changes. This is needed because the VPN exit IP is not stable.
Its web UI is available at mousehole.hdhomelab.com.
First-time setup:
- Go to mousehole.hdhomelab.com.
- Retrieve your MAM session cookie (
mam_id) from your browser while logged in to myanonamouse.net. - Paste the cookie into the Mousehole web UI and save.
Mousehole will immediately sync the current VPN IP and re-check every 5 minutes. State persists to an NFS-backed PVC at /srv/mousehole.
Tip
If MAM reports your IP as wrong, open Mousehole and click Force Update to push the current VPN IP immediately.
qui¶
qui is a modern web UI for qBittorrent with multi-instance support, automations, and cross-seed. It runs as a sidecar in the same pod, reaching qBittorrent over localhost:8080. Authentication is handled entirely via Authentik OIDC — the built-in login is disabled.
qui stores instance credentials (the qBittorrent URL/username/password) encrypted in its PostgreSQL database, using QUI__SESSION_SECRET as the encryption key.
Session secret must be stable
If QUI__SESSION_SECRET is not pinned, qui generates a new random key on every pod restart and can no longer decrypt the stored qBittorrent password — prompting you to re-enter it every time. The secret is pinned via qui/session in Vault.
First-time instance setup:
- Open qui.hdhomelab.com and sign in via Authentik.
- Add a qBittorrent instance with URL
http://localhost:8080and your qBittorrent credentials. - Credentials are encrypted and stored in Postgres — no further setup needed.
Key Environment Variables¶
| Variable | Value |
|---|---|
TZ |
America/New_York |
PUID |
1034 |
PGID |
100 |
WEBUI_PORT |
8080 |