Cross-platform containerized torrent downloader behind VPN using Gluetun + qBittorrent
A production-ready, security-hardened Docker Compose stack that routes all torrent traffic through a VPN with leak protection, kill switch, and web UI access from your local network.
Supports Windows 10/11, Linux, and macOS (including Apple Silicon M1/M2/M3).
Want to get started in 5 minutes? See the Quick Start Guide for express installation and setup.
📦 One-Command Installation
Linux (Ubuntu, Debian, Fedora, etc.) - Homebrew:
brew tap ddmoney420/torrent-vpn-stack && brew install torrent-vpn-stackArch Linux / Manjaro - AUR:
yay -S torrent-vpn-stackmacOS (Intel & Apple Silicon) - Homebrew:
brew tap ddmoney420/torrent-vpn-stack && brew install torrent-vpn-stackWindows - Chocolatey (Pending Approval):
choco install torrent-vpn-stackThen follow the Quick Start Guide for setup.
- ✅ VPN Kill Switch - All traffic routed through VPN; no leaks if VPN drops
- ✅ DNS Leak Protection - DNS-over-TLS (DoT) to Cloudflare prevents DNS leaks
- ✅ IPv6 Disabled - Prevents IPv6 leaks (most VPNs don't support IPv6)
- ✅ Firewall Rules - Strict firewall allows only VPN and local network access
- ✅ No Root - qBittorrent runs as unprivileged user (configurable UID/GID)
- ✅ Automatic Health Checks - Monitors VPN connection and restarts if unhealthy
- ✅ Web UI Access - qBittorrent accessible from Mac and LAN devices
- ✅ Single .env Configuration - All settings in one file
- ✅ Persistent Storage - Config and downloads survive restarts
- ✅ Automated Port Forwarding - Syncs VPN forwarded port to qBittorrent (if supported)
- ✅ Setup Wizard - Interactive script for easy configuration
- ✅ Verification Tools - Scripts to check VPN connection and detect leaks
- ✅ Cross-Platform - Windows 10/11, Linux (Ubuntu, Debian, Fedora, Arch), macOS (Intel & Apple Silicon M1/M2/M3)
- ✅ Multiple VPN Providers - Supports Mullvad, NordVPN, ProtonVPN, Surfshark, PIA, and many more
- ✅ WireGuard & OpenVPN - Modern WireGuard (recommended) or classic OpenVPN
- ✅ Automated Backups - Native automation for all platforms (Task Scheduler, systemd/cron, launchd)
New User? Start with the ⚡ Quick Start Guide
- Prerequisites
- VPN Provider Selection
- Installation
- Quick Start (Inline)
- Detailed Setup
- Configuration
- Usage
- Security Notes
- Troubleshooting
- FAQ
- Architecture
- Contributing
- License
- Operating System: Windows 10/11, Linux (Ubuntu 20.04+, Debian 11+, Fedora 35+, Arch), or macOS 11+
- Docker: Docker Desktop (Windows/macOS) or Docker Engine (Linux)
- Docker Compose: v2.0+ (included with Docker Desktop)
- VPN Subscription: One of the supported providers
- VPN Credentials: WireGuard config or OpenVPN username/password
- 8 GB RAM (4 GB minimum)
- 20 GB free disk space (more for downloads)
- Stable internet connection
Choose your platform for detailed installation instructions:
- Windows Installation Guide - WSL 2, Git Bash, PowerShell automation
- Linux Installation Guide - Ubuntu, Debian, Fedora, Arch, systemd/cron
- macOS Installation Guide - Intel and Apple Silicon, launchd automation
Choosing the right VPN provider is critical for torrent performance.
| Provider | Speed | Privacy | Price/Month | Notes |
|---|---|---|---|---|
| ProtonVPN Plus | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | $4.99+ | Swiss privacy, port forwarding on Plus+ plans |
| Private Internet Access | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | $2.19+ | Budget-friendly, port forwarding supported |
| Provider | Why Not Recommended |
|---|---|
| Mullvad | Port forwarding discontinued July 2023, excellent privacy but limited torrent performance |
| NordVPN | No port forwarding = 60-70% fewer peers, poor seeding |
| Surfshark | No port forwarding, limited torrent performance |
| ExpressVPN | No port forwarding, expensive, no WireGuard |
Port forwarding allows incoming connections = 2-3x more peers = faster downloads and better seeding.
- Best Performance: ProtonVPN Plus (port forwarding + WireGuard + Swiss privacy)
- Best Privacy: Mullvad (no port forwarding since July 2023) or ProtonVPN
- Best Budget: PIA ($2.19/month with port forwarding)
- Already Have Mullvad/NordVPN? Works, but expect slower speeds without port forwarding
📖 Full comparison: docs/provider-comparison.md
⚡ Performance tuning: docs/performance-tuning.md
🔧 Provider examples: See examples/providers/ for ready-to-use configurations
If your VPN provider is not natively supported by Gluetun, you can use custom WireGuard mode:
# In .env, use:
VPN_SERVICE_PROVIDER=custom
VPN_TYPE=wireguard
# Required fields from your provider's WireGuard config:
WIREGUARD_PRIVATE_KEY=<from [Interface] PrivateKey>
WIREGUARD_ADDRESSES=<from [Interface] Address>
WIREGUARD_PUBLIC_KEY=<from [Peer] PublicKey>
WIREGUARD_ENDPOINT_IP=<from [Peer] Endpoint, IP only>
WIREGUARD_ENDPOINT_PORT=<from [Peer] Endpoint, port only>📄 Full example: See examples/providers/custom.env.example
Choose your preferred installation method:
Install with a single command using your platform's package manager:
Supports: Ubuntu, Debian, Fedora, openSUSE, Rocky Linux, AlmaLinux, and more!
# Option 1: Install from tap
brew tap ddmoney420/torrent-vpn-stack
brew install torrent-vpn-stack
# Option 2: Install directly
brew install ddmoney420/torrent-vpn-stack/torrent-vpn-stack
# Quick start after installation
cd $(brew --prefix)/opt/torrent-vpn-stack
torrent-vpn-setup
docker compose up -dArch users can use AUR instead of Homebrew:
# Using yay
yay -S torrent-vpn-stack
# Using paru
paru -S torrent-vpn-stack
# Quick start after installation
cd /usr/share/torrent-vpn-stack
torrent-vpn-setup
docker compose up -d# Install from tap
brew tap ddmoney420/torrent-vpn-stack
brew install torrent-vpn-stack
# Quick start after installation
cd $(brew --prefix)/opt/torrent-vpn-stack
torrent-vpn-setup
docker compose up -dSubmitted - Pending Moderation
# Will be available as (pending approval):
choco install torrent-vpn-stack
# Quick start after installation
cd $env:ProgramData\torrent-vpn-stack
torrent-vpn-setup
docker compose up -d📖 Chocolatey Installation Guide Status: Resubmitted with fixes - pending moderation (24-48 hours) Note: Fixed Docker dependency issue, now checks for Docker in install script
If you prefer manual installation or your platform doesn't have a package manager:
# Clone the repository
git clone https://github.com/ddmoney420/torrent-vpn-stack.git
cd torrent-vpn-stack
# Run the setup wizard (recommended for first-time setup)
./scripts/setup.sh
# Or manually copy and edit the configuration
cp .env.example .env
nano .env # Edit with your VPN credentialsThis guide assumes you've already installed via one of the methods above. If using manual installation, start here:
For WireGuard (Recommended):
- Mullvad: Account → WireGuard Config
- ProtonVPN: Account → Downloads → WireGuard
- NordVPN: Dashboard → Manual Setup → WireGuard
For OpenVPN:
- Use your VPN account username and password
# Package manager installations
torrent-vpn-setup # Available system-wide
# Manual installation
./scripts/setup.shThe interactive wizard will guide you through:
- VPN provider selection
- VPN credentials configuration
- Network settings
- Downloads path
- Security settings
# Start all services in detached mode
docker compose up -d
# Check logs to verify VPN connection
docker compose logs -f gluetun
# Look for: "You are running on the bleeding edge of latest"
# and "ip getter: 1.2.3.4" (your VPN IP, not your real IP)Open http://localhost:8080 (or your configured QBITTORRENT_WEBUI_PORT)
Default Credentials:
- Username:
admin - Password:
adminadmin(CHANGE THIS IMMEDIATELY in Settings → Web UI)
# Package manager installations
torrent-vpn-verify # Verify VPN connection
torrent-vpn-check-leaks # Check for DNS/IP leaks
# Manual installation
./scripts/verify-vpn.sh
./scripts/check-leaks.shEdit .env and configure the following critical settings:
VPN_SERVICE_PROVIDER=mullvad # Your VPN provider
VPN_TYPE=wireguard # wireguard or openvpnWIREGUARD_PRIVATE_KEY=your_private_key_here
WIREGUARD_ADDRESSES=10.2.0.2/32DOWNLOADS_PATH=~/Downloads/torrents # Where files will be savedLOCAL_SUBNET=192.168.1.0/24 # Your home network subnetFind your subnet:
# macOS
ipconfig getifaddr en0 | awk -F. '{print $1"."$2"."$3".0/24"}'
# Or check your router's DHCP rangeQBITTORRENT_PASS=your_strong_password_here # CHANGE FROM DEFAULT!Get your user and group IDs:
id -u # User ID (PUID)
id -g # Group ID (PGID)Update in .env:
PUID=501 # Your user ID
PGID=20 # Your group IDmkdir -p ~/Downloads/torrentsPort forwarding significantly improves torrent performance by allowing incoming peer connections.
Supported Providers: ProtonVPN (Plus+), Private Internet Access (PIA)
Edit .env:
VPN_PORT_FORWARDING=on
# For ProtonVPN only, also set:
VPN_PORT_FORWARDING_PROVIDER=protonvpn
# Optional: Adjust sync interval (default: 300 seconds)
PORT_SYNC_INTERVAL=300The port sync helper runs as a Docker Compose profile. Start the stack with:
docker compose --profile port-forwarding up -dThe gluetun-qbittorrent-port-manager service will automatically sync the forwarded port from Gluetun to qBittorrent whenever it changes.
📖 For detailed setup, verification, and troubleshooting, see docs/port-forwarding.md
# Start in detached mode
docker-compose up -d
# Check status
docker-compose ps
# View logs
docker-compose logs -f
# View only VPN logs
docker-compose logs -f gluetun- Open http://localhost:8080
- Login with default credentials (admin/adminadmin)
- Immediately change password: Settings → Web UI → Authentication
- Configure downloads path: Settings → Downloads → Default Save Path:
/downloads - Disable UPnP/NAT-PMP: Settings → Connection → uncheck both (VPN handles this)
- Set connection port: Settings → Connection → Listening Port:
6881(or your configured port)
# Run all verification checks
./scripts/verify-vpn.sh
# Expected output:
# ✅ VPN container is running
# ✅ VPN IP detected: 1.2.3.4 (not your real IP)
# ✅ DNS leak test passed
# ✅ qBittorrent is accessible
# ✅ No IPv6 leaks detectedSee .env.example for full documentation of all variables.
Critical Settings:
| Variable | Required | Default | Description |
|---|---|---|---|
VPN_SERVICE_PROVIDER |
Yes | - | Your VPN provider (mullvad, nordvpn, protonvpn, etc.) |
VPN_TYPE |
Yes | wireguard | Protocol: wireguard or openvpn |
WIREGUARD_PRIVATE_KEY |
Yes* | - | Your WireGuard private key (*if using WireGuard) |
WIREGUARD_ADDRESSES |
Yes* | - | Your WireGuard IP address (*if using WireGuard) |
DOWNLOADS_PATH |
Yes | ./downloads | Local path for downloaded files |
LOCAL_SUBNET |
Yes | 192.168.1.0/24 | Your home network subnet for LAN access |
QBITTORRENT_PASS |
Yes | adminadmin | Web UI password (CHANGE THIS!) |
The stack exposes these ports on your Mac:
| Port | Service | Purpose |
|---|---|---|
| 8080 | qBittorrent Web UI | Browser access to qBittorrent |
| 6881 | qBittorrent Connections | Default torrent peer connections (TCP/UDP) |
| 8000 | Gluetun Control | Health checks and port forwarding info (optional) |
| Dynamic | VPN Port Forwarding | Auto-assigned by VPN provider (if enabled) |
Note: All ports are defined on the gluetun service because qBittorrent uses Gluetun's network stack (network_mode: service:gluetun). This is intentional for the kill switch.
Port Forwarding: When enabled, your VPN provider assigns a dynamic port (e.g., 51234) that automatically syncs to qBittorrent. See docs/port-forwarding.md for setup.
Persistent Volumes:
gluetun-config- VPN configuration and stateqbittorrent-config- qBittorrent settings and torrent metadata${DOWNLOADS_PATH}- Downloaded files (bind mount to your Mac)
Backup Important Data:
# Backup qBittorrent config (includes torrent list and settings)
docker run --rm -v torrent-vpn-stack_qbittorrent-config:/config -v $(pwd):/backup alpine tar czf /backup/qbittorrent-backup.tar.gz -C /config .
# Restore from backup
docker run --rm -v torrent-vpn-stack_qbittorrent-config:/config -v $(pwd):/backup alpine sh -c "cd /config && tar xzf /backup/qbittorrent-backup.tar.gz"# Start all services
docker-compose up -d
# Stop all services (keeps data)
docker-compose down
# Stop and remove volumes (DELETES ALL DATA)
docker-compose down -v
# Restart specific service
docker-compose restart gluetun
docker-compose restart qbittorrent
# View logs
docker-compose logs -f
docker-compose logs -f gluetun # VPN logs only
docker-compose logs -f qbittorrent # qBittorrent logs onlyTo access qBittorrent from other devices on your network:
- Find your Mac's IP:
ipconfig getifaddr en0 - Open
http://YOUR_MAC_IP:8080from another device - Ensure your
LOCAL_SUBNETin.envincludes that device's IP
Security Warning: Anyone on your LAN can access qBittorrent's Web UI. Use a strong password and consider IP allowlisting in qBittorrent's settings.
# Pull latest images
docker-compose pull
# Restart with new images
docker-compose up -d
# Clean up old images
docker image pruneCheck VPN Connection:
# Get current VPN IP
docker exec gluetun wget -qO- https://api.ipify.org
# Should return your VPN IP, NOT your real IP
# Check Gluetun health
curl http://localhost:8000/v1/publicip/ipCheck qBittorrent Status:
# Via Web UI: http://localhost:8080
# Or via API:
curl -u admin:your_password http://localhost:8080/api/v2/app/versionView Port Forwarding (if enabled):
curl http://localhost:8000/v1/openvpn/portforwardedEnable comprehensive monitoring with Prometheus + Grafana:
# Start stack with monitoring enabled
docker compose --profile monitoring up -dFeatures:
- Grafana Dashboards: Visual metrics at http://localhost:3000
- System: Container CPU, memory, network usage
- qBittorrent: Download/upload speeds, torrents, peers, ratio
- VPN: Connection status, uptime, throughput
- Prometheus: Metrics collection at http://localhost:9090
- 30-day retention: Historical trend analysis
- Real-time updates: Auto-refresh every 10 seconds
Access:
- Grafana: http://localhost:3000 (login: admin/admin)
- Prometheus: http://localhost:9090
📖 For detailed setup and dashboard guide, see docs/monitoring.md
Protect your configuration with automated or manual backups:
# Manual backup
./scripts/backup.sh
# Setup automated daily backups (macOS)
./scripts/setup-backup-automation.shFeatures:
- Backs up qBittorrent config, Gluetun config, and optionally monitoring data
- Automated daily backups via macOS launchd
- 7-day retention by default (configurable)
- Easy restore with interactive selection
Restore from backup:
# List available backups
./scripts/restore.sh --list
# Interactive restore
./scripts/restore.sh📖 For complete backup guide, see docs/backups.md
The kill switch works through Docker's network isolation:
- qBittorrent uses
network_mode: service:gluetun - All qBittorrent traffic must go through Gluetun's network stack
- If Gluetun's VPN drops, qBittorrent has no route to the internet
- Gluetun's firewall blocks all non-VPN traffic
Test the Kill Switch:
# Stop VPN while qBittorrent is running
docker-compose stop gluetun
# Try to access internet from qBittorrent container (should fail)
docker exec qbittorrent wget -T 5 -O- https://api.ipify.org
# Expected: Connection timeout/failureLayers of Protection:
- DNS-over-TLS (DoT) - Gluetun uses encrypted DNS to Cloudflare
- Custom DNS servers - Bypasses your ISP's DNS
- IPv6 disabled - Prevents IPv6 DNS leaks
- Firewall rules - Blocks DNS queries outside VPN tunnel
Verify DNS:
./scripts/check-leaks.sh
# Or manually:
docker exec qbittorrent nslookup google.com
# Should resolve through Cloudflare (1.1.1.1) or VPN DNSIPv6 is disabled by default because:
- Most VPN providers don't support IPv6
- IPv6 can leak your real location
- Torrents don't require IPv6
If you need IPv6 (rare), ensure your VPN supports it first.
Gluetun's firewall allows:
- ✅ VPN traffic
- ✅ Local subnet (your home network)
- ✅ Incoming torrent connections on configured port
- ❌ Everything else (kill switch)
Firewall is configured via:
FIREWALL_OUTBOUND_SUBNETS=192.168.1.0/24 # Your local network
FIREWALL_VPN_INPUT_PORTS=6881 # Torrent port- qBittorrent runs as non-root user (PUID/PGID)
- Gluetun requires
NET_ADMINcapability (minimum for VPN) - No unnecessary capabilities granted
- Read-only root filesystem where possible
CRITICAL: Never commit .env to version control!
.env
*.env
!.env.exampleSecure Your .env:
chmod 600 .env # Only you can read/writeSymptoms: Gluetun logs show connection errors, timeouts, or "context canceled"
Solutions:
-
Verify credentials:
grep WIREGUARD_PRIVATE_KEY .env # Should not be empty -
Check VPN provider status - Visit your provider's status page
-
Try different server:
SERVER_COUNTRIES=Sweden # Or another country
-
Enable debug logging:
LOG_LEVEL=debug
Then check logs:
docker-compose logs gluetun | grep -i error -
Verify Docker has internet:
docker run --rm alpine wget -O- https://cloudflare.com
Symptoms: Using VPN_SERVICE_PROVIDER=custom but VPN won't connect
Solutions:
-
"endpoint IP is not set" error:
# All fields are REQUIRED for custom provider: WIREGUARD_ENDPOINT_IP=1.2.3.4 WIREGUARD_ENDPOINT_PORT=51820
-
"private key is not valid" error:
- Check for copy/paste errors (extra spaces, missing characters)
- Ensure the full key is copied (usually ends with
=)
-
Connection timeout (no internet after connect):
- Verify
WIREGUARD_ADDRESSESmatches your provider's config exactly - Verify
WIREGUARD_PUBLIC_KEYis the server's public key (from[Peer]section) - Test endpoint is reachable:
nc -vz -u <endpoint_ip> 51820
- Verify
-
"endpoint port is set" error with built-in provider:
- Remove or leave empty:
WIREGUARD_ENDPOINT_PORT= - Built-in providers auto-detect the port
- Remove or leave empty:
Symptoms: Can't access http://localhost:8080 or qBittorrent won't start
Solutions:
-
Wait for Gluetun to be healthy:
docker-compose ps # Gluetun should show "healthy"qBittorrent won't start until Gluetun is healthy (by design).
-
Check port conflicts:
lsof -i :8080 # Should only show DockerIf another service uses 8080, change
QBITTORRENT_WEBUI_PORTin.env. -
Check container logs:
docker-compose logs qbittorrent | grep -i error
Symptoms: Accessing the Web UI shows "Unauthorized" instead of a login page
Solutions:
-
Disable host header validation (required for Docker):
# Stop qBittorrent docker-compose stop qbittorrent # Edit config (find your volume path) docker run --rm -v torrent-vpn-stack_qbittorrent-config:/config alpine sh -c ' cat >> /config/qBittorrent/qBittorrent.conf << EOF WebUI\HostHeaderValidation=false WebUI\CSRFProtection=false WebUI\LocalHostAuth=false EOF' # Restart docker-compose start qbittorrent
-
Check the temporary password (first run only):
docker-compose logs qbittorrent | grep -i password
Symptoms: Torrents stuck in "Stalled" or "Downloading" with 0 peers
Solutions:
-
Check VPN connection:
./scripts/verify-vpn.sh
-
Verify port forwarding (if enabled):
curl http://localhost:8000/v1/openvpn/portforwarded # Should return a port numberThen check qBittorrent Settings → Connection → Port matches this number.
-
Disable problematic settings in qBittorrent:
- Settings → Connection → Disable UPnP/NAT-PMP
- Settings → Connection → Disable "Use different port on each startup"
-
Try a different VPN server - Some servers may block torrent traffic
-
Check if you're firewalled:
- A 🔥 fire icon in qBittorrent means you're behind a firewall
- Enable port forwarding or use a VPN server that supports it
Symptoms: ./scripts/check-leaks.sh shows your ISP's DNS
Solutions:
-
Verify DoT is enabled:
docker-compose logs gluetun | grep -i "dns" # Should see "DNS over TLS" enabled
-
Force DNS-over-TLS:
DOT=on DOT_PROVIDERS=cloudflare
-
Check for IPv6 leaks:
docker exec qbittorrent ip -6 addr # Should be empty or only show local IPv6
Symptoms: Can't write to downloads folder, permission denied errors
Solutions:
# Fix ownership
sudo chown -R $(id -u):$(id -g) ~/Downloads/torrents
# Update PUID/PGID in .env to match your user
id -u # Use this for PUID
id -g # Use this for PGIDSymptoms: Slow performance, containers restarting
Solutions:
- Docker Desktop → Settings → Resources
- Increase RAM to 4GB+
- Increase Swap to 2GB+
- Increase Disk image size if low on space
All images used support ARM64 (Apple Silicon). If you see warnings about platform:
# Force ARM64 platform
DOCKER_DEFAULT_PLATFORM=linux/arm64 docker-compose up -dSymptoms: qBittorrent works on Mac but not from other devices
Solutions:
-
Check firewall:
# Temporarily disable macOS firewall to test sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate offIf it works, add Docker to firewall allowlist.
-
Verify LOCAL_SUBNET:
LOCAL_SUBNET=192.168.1.0/24 # Must match your network
Find your network:
netstat -nr | grep default -
Check Docker port binding:
lsof -i :8080 | grep LISTEN # Should show 0.0.0.0:8080 (not 127.0.0.1:8080)
A: Torrenting itself is legal. Using a VPN is legal. Downloading copyrighted material without permission is illegal. This stack is a tool; you are responsible for how you use it.
A: With this setup and a proper VPN:
- Your ISP sees encrypted VPN traffic only
- They cannot see what you're downloading
- They cannot see torrent protocol
- All DNS queries are encrypted (DoT)
However: Your ISP knows you're using a VPN. In some jurisdictions, that alone may raise flags.
A: Look for:
- ✅ WireGuard support
- ✅ Port forwarding support (optional but improves speeds)
- ✅ No-logging policy
- ✅ Fast speeds (10+ Gbps servers)
- ✅ P2P/torrenting allowed
Recommended (with port forwarding):
- ProtonVPN - Port forwarding, secure core, Switzerland-based
- Private Internet Access (PIA) - Port forwarding, many servers, affordable
Good privacy but no port forwarding:
- Mullvad - Best privacy, flat rate (port forwarding discontinued July 2023)
Avoid:
- Free VPNs (slow, logging, malware)
- VPNs that block P2P traffic
- VPNs in 14-Eyes countries (if privacy is critical)
A: Not required, but highly recommended for optimal performance:
- Without: You can download, but only from peers who have port forwarding (limited connectivity)
- With: You become "connectable" — faster speeds, better seeding, healthier swarms
Supported Providers: ProtonVPN (Plus+), Private Internet Access (PIA)
📖 See docs/port-forwarding.md for complete setup guide
A:
- VPN: $5-15/month (depends on provider, cheaper with annual plans)
- This stack: Free and open source
- Docker Desktop: Free (paid for enterprise use)
A: Yes! Fully cross-platform support:
- ✅ Windows 10/11 - Native support with WSL2 or Git Bash (install via Chocolatey)
- ✅ Linux - Ubuntu, Debian, Fedora, Arch, etc. (install via Homebrew or AUR)
- ✅ macOS - Intel and Apple Silicon M1/M2/M3 (install via Homebrew)
See the Installation section for platform-specific package managers and detailed guides in docs/.
A: Yes, but you'll need separate VPN credentials for each:
- Copy the entire folder:
cp -r torrent-vpn-stack torrent-vpn-stack-2 - Change container names in
docker-compose.yml - Change ports in
.env(8081, 6882, etc.) - Use different VPN credentials
A: Use OpenVPN:
VPN_TYPE=openvpn
OPENVPN_USER=your_username
OPENVPN_PASSWORD=your_passwordWireGuard is faster and more modern, but OpenVPN works fine.
A: Run the verification:
./scripts/check-leaks.sh
# Or manually check your IP:
docker exec qbittorrent wget -qO- https://api.ipify.org
# Should show VPN IP, NOT your real IPA: Not recommended:
- ❌ Free VPNs often log and sell your data
- ❌ Slow speeds (congested servers)
- ❌ Block P2P traffic
- ❌ Data caps
- ❌ Some inject ads or malware
Quality VPNs cost $3-10/month with annual plans.
A: The kill switch activates:
- qBittorrent loses all internet connectivity
- All torrent traffic stops immediately
- Your real IP is never exposed
- Gluetun attempts to reconnect automatically
- When VPN reconnects, torrenting resumes
A: If your qBittorrent Web UI is accessible from outside your home:
- Don't expose it directly to the internet (security risk!)
- Use a VPN to your home network (Tailscale, WireGuard, ZeroTier)
- Or use a reverse proxy with authentication (Traefik, nginx)
- Or use qBittorrent's mobile apps (connect via VPN)
Never port forward qBittorrent Web UI to the internet without strong auth + IP allowlist!
See docs/architecture.md for detailed architecture diagrams and flow charts.
High-Level Overview:
┌─────────────────────────────────────────────────────────────────────┐
│ Host System (Windows / Linux / macOS) │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Docker Compose Stack │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ Gluetun (VPN Gateway) │ │ │
│ │ │ ┌──────────────────────────────────────────────────┐ │ │ │
│ │ │ │ • WireGuard/OpenVPN client │ │ │ │
│ │ │ │ • Firewall (kill switch) │ │ │ │
│ │ │ │ • DNS-over-TLS (DoT) │ │ │ │
│ │ │ │ • IPv6 disabled │ │ │ │
│ │ │ │ • Port forwarding │ │ │ │
│ │ │ │ • Health monitoring │ │ │ │
│ │ │ └──────────────────────────────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ Exposes ports to host: │ │ │
│ │ │ - 8080 (qBittorrent Web UI) │ │ │
│ │ │ - 6881 (Torrent connections) │ │ │
│ │ │ - 8000 (Gluetun control - optional) │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ │ ▲ │ │
│ │ │ network_mode: service:gluetun │ │
│ │ │ (Shares network namespace) │ │
│ │ ┌─────────────────────────┴────────────────────────────┐ │ │
│ │ │ qBittorrent (Torrent Client) │ │ │
│ │ │ • Shares Gluetun's network namespace │ │ │
│ │ │ • All traffic forced through VPN tunnel │ │ │
│ │ │ • No independent internet access (kill switch) │ │ │
│ │ │ • Web UI accessible @ http://localhost:8080 │ │ │
│ │ │ • Runs as unprivileged user (PUID/PGID) │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │ │
│ │ Bind mount to host filesystem │
│ ▼ │
│ Downloads Path (configurable): │
│ • Windows: C:\Users\<user>\Downloads\torrents │
│ • Linux: /home/<user>/Downloads/torrents │
│ • macOS: /Users/<user>/Downloads/torrents │
│ │
│ Docker Volumes (persistent config): │
│ • gluetun-config (VPN state) │
│ • qbittorrent-config (settings & torrents) │
└─────────────────────────────────────────────────────────────────────┘
│
│ Encrypted VPN Tunnel
│ (WireGuard or OpenVPN)
▼
Internet via VPN Provider
(Your real IP is never exposed)
Traffic Flow:
- qBittorrent → Gluetun's network stack (forced, no alternatives)
- Gluetun → Firewall check → Allowed?
- If VPN up: Encrypt → VPN server → Internet
- If VPN down: Drop packet (kill switch)
No traffic can leave qBittorrent without going through the VPN.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
Areas for contribution:
- Additional VPN provider examples
- Setup wizard improvements
- More verification scripts
- Platform-specific guides (Linux, Windows)
- Performance optimizations
- Security hardening
MIT License - See LICENSE file for details
- Gluetun by @qdm12 - Excellent VPN client container
- LinuxServer.io - qBittorrent Docker image
- qBittorrent - Feature-rich torrent client
This tool is provided for educational and legitimate use only. The authors are not responsible for any misuse or illegal activity. Always comply with copyright laws and terms of service of your VPN provider and ISP.
Contributions are welcome! This is an open source project under the MIT License.
- 🤝 Contributing Guide - How to contribute code, documentation, or bug reports
- 🔒 Security Policy - Reporting vulnerabilities responsibly
- 📜 Code of Conduct - Community standards
- 📝 MIT License - Free and open source
- Report bugs or suggest features via GitHub Issues
- Improve documentation (especially platform-specific guides)
- Test on different platforms and report compatibility
- Submit pull requests for bug fixes or enhancements
- Help answer questions in Discussions
See CONTRIBUTING.md for detailed guidelines.
Made with ❤️ for privacy-conscious torrenters
Research Sources:
- Gluetun with ProtonVPN Discussion
- Port Conflicts with Gluetun and qBittorrent
- qBittorrent with GlueTUN VPN Setup Guide
- Troubleshooting Errored Status
- YAMS Installation Issues
- Gluetun API Connection Issue
- AirVPN Troubleshooting Guide
- Gluetun+qBittorrent Bug Report
- Automated Port Manager
- QBittorrent with Gluetun Setup