BitTorrent
Prerequisite: NGINX
Use torrents legally and responsibly.
For media automation, the torrent client is one of the core building blocks.
The stack I recommend here is:
- qBittorrent for the actual BitTorrent client
- Gluetun to force that traffic through your VPN
- optional VueTorrent as a nicer qBittorrent web UI
The important concept is this:
If you use BitTorrent, route that traffic through a VPN on purpose. Do not treat that as optional hygiene.
Why qBittorrent + Gluetun?
Because it solves the right problem cleanly:
- qBittorrent is reliable and widely supported
- Gluetun provides a VPN container that other containers can share
- if the VPN is down, the torrent client should not quietly fall back to your normal WAN path
That containment matters.
Prepare Download Paths
Create a place for in-progress and completed downloads.
If you have TrueNAS mounted, I recommend keeping this on the NAS:
mkdir -p /mnt/nas/media/downloads
mkdir -p /mnt/nas/media/downloads/torrents
mkdir -p ~/docker/appdata/qbittorrent
mkdir -p ~/docker/compose/downloads
If you skipped TrueNAS, use a local path for now and migrate later.
Create the Compose File
Create ~/docker/compose/downloads/bittorrent.compose.yml:
services:
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun
cap_add:
- NET_ADMIN
ports:
- "8082:8080"
- "6881:6881"
- "6881:6881/udp"
environment:
- VPN_SERVICE_PROVIDER=YOUR_PROVIDER
- OPENVPN_USER=YOUR_USERNAME
- OPENVPN_PASSWORD=YOUR_PASSWORD
- SERVER_COUNTRIES=United States
- TZ=America/New_York
restart: unless-stopped
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
network_mode: "service:gluetun"
depends_on:
- gluetun
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
- WEBUI_PORT=8080
volumes:
- /home/<your-user>/docker/appdata/qbittorrent:/config
- /mnt/nas/media/downloads:/downloads
restart: unless-stopped
Replace the VPN variables with values for your provider.
If your provider prefers WireGuard instead of OpenVPN, follow the Gluetun documentation for the appropriate environment variables.
Start the Stack
docker compose -f ~/docker/compose/downloads/bittorrent.compose.yml up -d
Open qBittorrent at:
http://<nixos-ip>:8082
Set a new admin password immediately.
Optional: VueTorrent
If you want a more modern interface, use VueTorrent as qBittorrent’s custom web UI:
https://github.com/VueTorrent/VueTorrent
I am not putting it in the baseline compose file because qBittorrent itself is the critical piece, not the skin on top.
Get the client working first. Make it pretty second.
Test the VPN Assumption
Do not just assume the VPN path is working because the container started.
Verify:
- qBittorrent is reachable
- downloads can start normally
- the VPN container logs look healthy
- you understand which container actually owns the network namespace
If you do not understand that last point, stop and fix that before layering automation on top of it.
Security and Exposure
My recommendation:
- keep qBittorrent private
- access it only from LAN or Tailscale
There is almost never a good reason to expose your torrent client’s web UI publicly.
Next Steps
Next, we will add the automation layer on top of this: Sonarr, Radarr and related services for movies and TV.
Proceed to Movies/TV.
Last updated: March 2026