Files
rtomik-helm-charts/charts/qbittorrent-vpn/readme.md
2026-04-13 16:15:48 +02:00

304 lines
9.4 KiB
Markdown

# qBittorrent VPN Helm Chart
A Helm chart for deploying [qBittorrent](https://www.qbittorrent.org/) with a [Gluetun](https://github.com/qdm12/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
```bash
helm repo add rtomik https://rtomik.github.io/helm-charts
helm install qbittorrent-vpn rtomik/qbittorrent-vpn
```
## Uninstalling the Chart
```bash
helm uninstall qbittorrent-vpn
```
**Note**: PVCs are not deleted automatically. To remove them:
```bash
kubectl delete pvc -l app.kubernetes.io/instance=qbittorrent-vpn
```
## Configuration Examples
### NordVPN with Existing Secret
First, create a secret with your VPN credentials:
```bash
kubectl create secret generic vpn-credentials \
--from-literal=username='your-vpn-username' \
--from-literal=password='your-vpn-password'
```
```yaml
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
```yaml
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
```yaml
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
```yaml
service:
proxies:
enabled: true
httpPort: 8888
socksPort: 8388
```
### Custom Sidecar (NATMap)
Sidecars can access shared volumes: `config`, `downloads`, and `gluetun-config`.
```yaml
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](https://github.com/qdm12/gluetun-wiki/tree/main/setup/providers) for the full list and provider-specific options.
## Troubleshooting
### VPN Not Connecting
```bash
kubectl logs deployment/qbittorrent-vpn -c gluetun
kubectl describe secret vpn-credentials
```
Enable debug logging for more detail:
```yaml
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.
## Links
- [qBittorrent](https://www.qbittorrent.org/)
- [Gluetun GitHub](https://github.com/qdm12/gluetun)
- [Gluetun Provider Setup](https://github.com/qdm12/gluetun-wiki/tree/main/setup/providers)
- [Chart Source](https://github.com/rtomik/helm-charts/tree/main/charts/qbittorrent-vpn)