Files
rtomik-helm-charts/charts/qbittorrent-vpn
2026-04-13 16:15:48 +02:00
..
2025-12-17 15:59:50 +01:00
2025-12-17 15:59:50 +01:00
2026-04-13 16:15:48 +02:00
2025-12-17 15:59:50 +01:00

qBittorrent VPN Helm Chart

A Helm chart for deploying qBittorrent with a Gluetun VPN sidecar on Kubernetes.

Introduction

This chart deploys qBittorrent alongside Gluetun, ensuring all BitTorrent traffic is routed through a VPN. It supports 30+ VPN providers via OpenVPN or WireGuard, includes a kill-switch firewall, and exposes HTTP/Socks proxy services.

Source code: https://github.com/rtomik/helm-charts/tree/main/charts/qbittorrent-vpn

Note: Currently only tested with NordVPN and OpenVPN configuration.

Prerequisites

  • Kubernetes 1.19+
  • Helm 3.2.0+
  • PV provisioner support in the cluster
  • A valid VPN subscription

Installing the Chart

helm repo add rtomik https://rtomik.github.io/helm-charts
helm install qbittorrent-vpn rtomik/qbittorrent-vpn

Uninstalling the Chart

helm uninstall qbittorrent-vpn

Note: PVCs are not deleted automatically. To remove them:

kubectl delete pvc -l app.kubernetes.io/instance=qbittorrent-vpn

Configuration Examples

NordVPN with Existing Secret

First, create a secret with your VPN credentials:

kubectl create secret generic vpn-credentials \
  --from-literal=username='your-vpn-username' \
  --from-literal=password='your-vpn-password'
gluetun:
  vpn:
    provider: "nordvpn"
    type: "openvpn"
    serverCountries: "United States"
    openvpn:
      NORDVPN_CATEGORY: "P2P"
  credentials:
    create: false
    existingSecret: "vpn-credentials"
    usernameKey: "username"
    passwordKey: "password"

ingress:
  enabled: true
  hosts:
    - host: qbittorrent.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - hosts:
        - qbittorrent.example.com

ProtonVPN

gluetun:
  vpn:
    provider: "protonvpn"
    type: "openvpn"
    serverCountries: "Switzerland"
    openvpn:
      PROTONVPN_TIER: "2"
      SERVER_FEATURES: "p2p"
  credentials:
    create: true
    username: "protonvpn-username"
    password: "protonvpn-password"

Private Internet Access with Port Forwarding

gluetun:
  vpn:
    provider: "private internet access"
    type: "openvpn"
    serverCountries: "US"
  credentials:
    create: true
    username: "pia-username"
    password: "pia-password"
  settings:
    VPN_PORT_FORWARDING: "on"
    STATUS_FILE: "/tmp/gluetun-status.json"

Proxy Services

service:
  proxies:
    enabled: true
    httpPort: 8888
    socksPort: 8388

Custom Sidecar (NATMap)

Sidecars can access shared volumes: config, downloads, and gluetun-config.

sidecars:
  - name: natmap
    image: ghcr.io/muink/natmap:latest
    imagePullPolicy: IfNotPresent
    env:
      - name: GATEWAY
        value: "10.2.0.1"
      - name: INTERFACE
        value: "tun0"
      - name: INTERVAL
        value: "30"
    volumeMounts:
      - name: config
        mountPath: /config
        subPath: natmap

Parameters

qBittorrent Parameters

Name Description Default
qbittorrent.image.repository qBittorrent image repository linuxserver/qbittorrent
qbittorrent.image.tag qBittorrent image tag 5.1.0
qbittorrent.image.pullPolicy Image pull policy IfNotPresent
qbittorrent.bittorrentPort BitTorrent traffic port 6881
qbittorrent.service.port Web UI port 8080

Gluetun VPN Parameters

Name Description Default
gluetun.enabled Enable Gluetun VPN sidecar true
gluetun.image.repository Gluetun image repository qmcgaw/gluetun
gluetun.image.tag Gluetun image tag v3.40.0
gluetun.vpn.provider VPN provider name nordvpn
gluetun.vpn.type VPN protocol (openvpn or wireguard) openvpn
gluetun.vpn.serverCountries Countries to connect (comma-separated) Netherlands
gluetun.vpn.serverCities Cities to connect (optional) ""
gluetun.vpn.serverNames Specific server names (optional) ""
gluetun.vpn.randomize Randomize server selection true

VPN Credentials

Name Description Default
gluetun.credentials.create Create credentials secret true
gluetun.credentials.username VPN username (if creating secret) ""
gluetun.credentials.password VPN password (if creating secret) ""
gluetun.credentials.existingSecret Existing secret name ""
gluetun.credentials.usernameKey Key for username in secret username
gluetun.credentials.passwordKey Key for password in secret password

Gluetun Settings

Name Description Default
gluetun.settings.FIREWALL Enable firewall on
gluetun.settings.FIREWALL_OUTBOUND_SUBNETS Allowed outbound subnets 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
gluetun.settings.FIREWALL_INPUT_PORTS Ports allowed through firewall 8080
gluetun.settings.FIREWALL_DEBUG Enable firewall debug on
gluetun.settings.VPN_PORT_FORWARDING Enable port forwarding off
gluetun.settings.DNS_ADDRESS DNS server address 1.1.1.1
gluetun.resources.limits.cpu CPU limit 300m
gluetun.resources.limits.memory Memory limit 256Mi

WireGuard Configuration (when using WireGuard)

Name Description Default
gluetun.vpn.wireguard.privateKey WireGuard private key ""
gluetun.vpn.wireguard.privateKeyExistingSecret Existing secret with private key ""
gluetun.vpn.wireguard.addresses WireGuard addresses ""
gluetun.vpn.wireguard.endpointIP Server endpoint IP (optional) ""
gluetun.vpn.wireguard.endpointPort Server endpoint port (optional) ""

Deployment Parameters

Name Description Default
replicaCount Number of replicas 1
revisionHistoryLimit Revisions to retain 3
podSecurityContext.runAsNonRoot Run as non-root false
podSecurityContext.runAsUser User ID 0
podSecurityContext.fsGroup Filesystem group ID 0
nodeSelector Node selector {}
tolerations Tolerations []
affinity Affinity rules {}

Service Parameters

Name Description Default
service.type Service type ClusterIP
service.port Service port 8080
service.proxies.enabled Enable HTTP/Socks proxy services false
service.proxies.httpPort HTTP proxy port 8888
service.proxies.socksPort Socks proxy port 8388

Ingress Parameters

Name Description Default
ingress.enabled Enable ingress false
ingress.className Ingress class name ""
ingress.annotations Ingress annotations []
ingress.hosts Ingress hosts See values.yaml
ingress.tls TLS configuration See values.yaml

Persistence Parameters

Name Description Default
qbittorrent.persistence.config.enabled Enable config PVC true
qbittorrent.persistence.config.existingClaim Existing config PVC ""
qbittorrent.persistence.config.size Config PVC size 2Gi
qbittorrent.persistence.downloads.enabled Enable downloads PVC true
qbittorrent.persistence.downloads.existingClaim Existing downloads PVC ""
qbittorrent.persistence.downloads.size Downloads PVC size 2Gi
gluetun.persistence.enabled Enable Gluetun config PVC true
gluetun.persistence.size Gluetun config PVC size 100Mi

Sidecar Parameters

Name Description Default
sidecars Additional sidecar containers []

Health Check Parameters

Name Description Default
probes.liveness.enabled Enable liveness probe true
probes.liveness.path Liveness probe path /
probes.liveness.periodSeconds Liveness period 30
probes.readiness.enabled Enable readiness probe true
probes.readiness.path Readiness probe path /
probes.readiness.periodSeconds Readiness period 10

Supported VPN Providers

AirVPN, Cyberghost, ExpressVPN, FastestVPN, HideMyAss, IPVanish, IVPN, Mullvad, NordVPN, Perfect Privacy, Private Internet Access, PrivateVPN, ProtonVPN, PureVPN, Surfshark, TorGuard, VyprVPN, WeVPN, Windscribe, and more.

See the Gluetun Providers Documentation for the full list and provider-specific options.

Troubleshooting

VPN Not Connecting

kubectl logs deployment/qbittorrent-vpn -c gluetun
kubectl describe secret vpn-credentials

Enable debug logging for more detail:

gluetun:
  extraEnv:
    - name: LOG_LEVEL
      value: "debug"

Directory Creation Errors

Ensure the init container is enabled and fsGroup is set in podSecurityContext.

Firewall / Network Issues

Gluetun requires privileged: true and NET_ADMIN capability. Verify /dev/net/tun is mounted correctly.