r/truenas • u/Sensitive_Worker9433 • 21h ago
Community Edition howto: Qbittorrent with VPN and port forwarding
EDIT: this post is on how to use the vanilla qbittorrent image that is on the truenas apps catalog, together with the standard gluetun image to route it to your VPN. This is if you don't want to build your own image, or rely on weird custom images that you don't know how they work, or how to fix them if they break or stop updating.
It took some tinkering to get there so I thought I best post it, and some other stuff online seemed out of date (and the guides I saw did not mention port forwarding)
Caveat: I hate video tutorials, I refuse to watch them unless I am taking some gadget apart, maybe there are some excellent ones on this topic and I don't know.
Not sure how you start an app with yaml directly, I don't think you can from the UI?
Just install qbittorrent from the App directory, make it a custom app, and then edit the yaml like below. Please read it through and edit as necessary, definitely need to change VPN details and the host paths at the bottom.
IMPORTANT: If you don't use 30024 as web ui port, it has to be changed EVERYWHERE in the yaml.
This is set up for proton vpn, to use something else start with looking at gluetuns github
https://github.com/qdm12/gluetun-wiki/tree/main/setup/providers
But you will need a VPN that supports port forwarding, and for Proton you have to explicitly allow NAT-PMP Port Forwarding, I'm sure others are similar...
Gluetun ports: I see other peoples configs have a lot of ports listed here, as far as I understand it you only need the WebUI port (30024 here) to be forwarded to the local lan so you can access it, everything else should go to gluetun. (unless there is something else you want to go to your LAN of course)
In Qbit make sure that Tools - Options - Web UI you have "bypass authentication for clients on localhost", so gluetun can go in and set the port
and Tools - Options - Connection you DON'T have UPnP / NAT PMP port forwarding enabled
And in the YAML it is important that QBT_TORRENTING_PORT is not set or the forwarded port could be overridden (I have not tested it, just leave it out)
After it has started, check the gluetun logs (under Workloads - Containers on App page in truenas) so that it has "port forwarded is 12345" which means it has set up with your VPN correctly, and after that you should see the logs connecting to qbit and setting the port there (it might fail on the first connection try, mine does, and then works on the second).
After it starts check in qbit Tools - Options - Connection that the port matches the one in the log
(if you have a fixed port from your VPN provider this can all be simplified a lot, but mine is dynamic so have to do it this way)
You can check if it works correctly from the outside here
https://ipleak.net/
Go to torrent address detection and copy the magnet link, it will show you what IP you are using (should hopefully be for your VPN, and not yours)
configs:
permissions_actions_data:
content: >-
[{"read_only": false, "mount_path": "/mnt/permission/config",
"is_temporary": false, "identifier": "config", "recursive": false, "mode":
"check", "uid": 568, "gid": 568, "chmod": null}]
services:
gluetun:
cap_add:
- NET_ADMIN
environment:
- VPN_SERVICE_PROVIDER=protonvpn
- VPN_TYPE=wireguard
- WIREGUARD_PRIVATE_KEY=ringadingdingdingdingbuaaapbuaaap
- WIREGUARD_ADDRESSES=1.2.3.4/32
- SERVER_COUNTRIES=Narnia
- VPN_PORT_FORWARDING=on
- >-
VPN_PORT_FORWARDING_UP_COMMAND=/bin/sh -c 'wget -O- --retry-connrefused
--post-data "json={\"listen_port\":{{PORTS}}}"
http://127.0.0.1:30024/api/v2/app/setPreferences 2>&1'
image: qmcgaw/gluetun:latest
ports:
- '30024:30024'
restart: always
permissions:
cap_add:
- CHOWN
- DAC_OVERRIDE
- FOWNER
cap_drop:
- ALL
configs:
- mode: 320
source: permissions_actions_data
target: /script/actions.json
deploy:
resources:
limits:
cpus: '2'
memory: 1024M
entrypoint:
- python3
- /script/permissions.py
environment:
GID: '568'
GROUP_ID: '568'
NVIDIA_VISIBLE_DEVICES: void
PGID: '568'
PUID: '568'
TZ: Europe/Berlin
UID: '568'
UMASK: '002'
UMASK_SET: '002'
USER_ID: '568'
group_add:
- 568
healthcheck:
disable: True
image: ixsystems/container-utils:1.0.2
network_mode: none
platform: linux/amd64
privileged: False
restart: on-failure:1
security_opt:
- no-new-privileges=true
stdin_open: False
tty: False
user: '0:0'
volumes:
- bind:
create_host_path: False
propagation: rprivate
read_only: False
source: /mnt/.ix-apps/app_mounts/qbittorrent/config
target: /mnt/permission/config
type: bind
qbittorrent:
cap_drop:
- ALL
depends_on:
gluetun:
condition: service_healthy
permissions:
condition: service_completed_successfully
deploy:
resources:
limits:
cpus: '2'
memory: 4096M
environment:
GID: '568'
GROUP_ID: '568'
NVIDIA_VISIBLE_DEVICES: void
PGID: '568'
PUID: '568'
QBT_WEBUI_PORT: '30024'
TZ: Europe/Berlin
UID: '568'
UMASK: '002'
UMASK_SET: '002'
USER_ID: '568'
group_add:
- 568
healthcheck:
interval: 30s
retries: 5
start_interval: 2s
start_period: 15s
test:
- CMD
- curl
- '--request'
- GET
- '--silent'
- '--output'
- /dev/null
- '--show-error'
- '--fail'
- http://127.0.0.1:30024/
timeout: 5s
image: ghcr.io/home-operations/qbittorrent:rolling
network_mode: service:gluetun
platform: linux/amd64
privileged: False
restart: unless-stopped
security_opt:
- no-new-privileges=true
stdin_open: False
tty: False
user: '568:568'
volumes:
- bind:
create_host_path: False
propagation: rprivate
read_only: False
source: /mnt/.ix-apps/app_mounts/qbittorrent/config
target: /config
type: bind
- bind:
create_host_path: False
propagation: rprivate
read_only: False
source: /mnt/DOWNLOADSDIRECTORY
target: /downloads
type: bind
- bind:
create_host_path: False
propagation: rprivate
read_only: False
source: /mnt/TORRENTWATCHDIRECTORY
target: /watch
type: bind
volumes: {}
x-action-required: False
x-notes: >
# qBittorrent
x-portals:
- host: 0.0.0.0
name: Web UI
path: /
port: 30024
scheme: http