Hello everyone, I recently tried switching my docker torrent client setup from haugene/transmission-openvpn to linuxserver/qbittorrent with gluetun for my VPN.
I have gluetun set up to use port forwarding with ProtonVPN which assigns a random port on every connection. Gluetun provides a VPN_PORT_FORWARDING_UP_COMMAND which can be used in this scenario to update the port used by qbittorrent. While I had issues with the example command in the gluetun wiki to do this, I eventually managed using a bash script I found in another forum.
My issue now is that my server shuts down for the night to reduce noise and after restarting, even though I have the container startup order set up, qbittorrent is no longer reachable on its webinterface. The logs do not indicate any issue though.
As far as I can tell, the stack as I have set it up is extremely finnicky in terms of startup order and time. If I start gluetun first and then wait too long before starting qbit, the port update script will fail because there is obviously no target for it. If qbit is up and running before gluetun is done, I typically can't access its webinterface for some reason and the network interface used by gluetun will set itself to loopback.
The result of this is that basically every morning I have to start and restart the containers in the stack a couple of times until I can access the interface and ensure that the port and network interface of qbit are configured correctly.
If anyone has a similar setup working that they could share or maybe another solution to my current issue that would be great. Thanks.
This is my docker-compose stack for the new setup
version: '3'
services:
gluetun:
image: qmcgaw/gluetun
container_name: gluetun
restart: unless-stopped
cap_add:
- NET_ADMIN
ports:
- 8080:8080 # qbittorrent webinterface
# - 6881:6881 # qbittorrent, only needed without port-forwarding
environment:
- VPN_SERVICE_PROVIDER=protonvpn
- OPENVPN_USER=${OPENVPN_USERNAME}
- OPENVPN_PASSWORD=${OPENVPN_PW}
- SERVER_COUNTRIES=Switzerland
- VPN_PORT_FORWARDING=on
- PORT_FORWARD_ONLY=on
- TZ=Europe/Berlin
# From gluetun wiki: https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/vpn-port-forwarding.md
- VPN_PORT_FORWARDING_UP_COMMAND=/bin/sh -c 'sh /gluetun/update-port.sh "{{PORTS}}"'
- VPN_PORT_FORWARDING_DOWN_COMMAND=/bin/sh -c 'echo "Execution port forwarding down command" && wget -O- -nv --retry-connrefused --post-data "json={\"listen_port\":0,\"current_network_interface\":\"lo\"}" http://127.0.0.1:8080/api/v2/app/setPreferences'
- QBIT_ADDRESS=http://localhost:8080/
- QBIT_USERNAME=${QBIT_USER}
- QBIT_PASSWORD=${QBIT_PW}
volumes:
- /mnt/truenas/qbittorrent/update_port.sh:/gluetun/update-port.sh
labels:
- "com.centurylinklabs.watchtower.enable=true" # Auto update using watchtower
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- WEBUI_PORT=8080
- TORRENTING_PORT=6881
network_mode: "service:gluetun"
depends_on:
- gluetun
# condition: service_healthy
# restart: true
volumes:
- /home/poseidon/qbittorrent:/config
- /mnt/truenas/qbittorrent:/downloads
# ports:
# - 8080:8080
# - 6881:6881
# - 6881:6881/udp
restart: unless-stopped
And this is the script I use for updating the qbittorrent ports
#!/bin/sh
# update-port.sh
port="$1"
retries="${UPDATE_PORT_RETRIES:-5}"
interval="${UPDATE_PORT_RETRY_INTERVAL:-10}"
echo "Attempting to update qBittorrent port to $port..."
for i in $(seq 1 "$retries"); do
response=$(wget --quiet --save-cookies=/tmp/cookies.txt --keep-session-cookies \
--post-data="username=$QBIT_USERNAME&password=$QBIT_PASSWORD" \
--header="Referer: $QBIT_ADDRESS" \
"$QBIT_ADDRESS/api/v2/auth/login" -O -)
if [ "$response" = "Ok." ]; then
break
fi
echo "Login attempt $i/$retries failed. Retrying in $interval seconds..."
sleep "$interval"
done
set -e
if [ "$response" != "Ok." ]; then
echo "Unable to log in to qBittorrent."
rm -f /tmp/cookies.txt
exit 1
fi
wget --quiet --load-cookies=/tmp/cookies.txt \
--post-data="json={\"listen_port\": $port, \"current_network_interface\":\"$VPN_INTERFACE\", ,\"random_port\":false,\"upnp\":false}" \
"$QBIT_ADDRESS/api/v2/app/setPreferences" -O /dev/null
rm -f /tmp/cookies.txt
echo "qBittorrent port updated successfully to $port."
Update
After updating my stack based on the recommendation from hyphen612 it has been running flawlessly for a few days. This is my new docker-compose file. The extra script I used before for updating the port has been retired.
version: '3'
services:
gluetun:
image: qmcgaw/gluetun
container_name: gluetun
restart: unless-stopped
cap_add:
- NET_ADMIN
ports:
- 8080:8080 # qbittorrent
# - 6881:6881 # deluge or qbittorrent, only needed without port-forwarding
environment:
- VPN_SERVICE_PROVIDER=protonvpn
- OPENVPN_USER=${OPENVPN_USERNAME}
- OPENVPN_PASSWORD=${OPENVPN_PW}
- SERVER_COUNTRIES=Switzerland
- VPN_PORT_FORWARDING=on
- PORT_FORWARD_ONLY=on
- IPV6=off
- TZ=Europe/Berlin
- VPN_PORT_FORWARDING_UP_COMMAND=/bin/sh -c 'wget -O- --retry-connrefused --post-data "json={\"listen_port\":{{PORTS}}}" http://127.0.0.1:8080/api/v2/app/setPreferences 2>&1'
- HEALTH_SUCCESS_WAIT_DURATION=20s
- HEALTH_TARGET_ADDRESSES='1.1.1.1:443'
healthcheck:
test: ["CMD", "/gluetun-entrypoint", "healthcheck"]
interval: 10s
timeout: 10s
start_period: 20s
retries: 10 #has internal fix mechanism
labels:
- "com.centurylinklabs.watchtower.enable=true" # Auto update using watchtower
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- WEBUI_PORT=8080
- TORRENTING_PORT=6881
network_mode: "service:gluetun"
depends_on:
gluetun:
condition: service_healthy
# restart: true
volumes:
- /home/poseidon/qbittorrent:/config
- /mnt/truenas/qbittorrent:/downloads
restart: unless-stopped
I kind of railroaded myself into using calibre unfortunately.
I have a very specific filenaming scheme which I originally came up with back when I only used folders for organising my books in order to group together books that belong to a series but where the series is part of a larger universe.
Basically my folder structure is {World}/{Reading Order}; {Series} #{Series_Index} - {Title} - {Author}
On my kobo I have the autoshelf plugin installed which automatically parses this information when I add books and groups them together by world while filling out the series information.
In order to properly make use of this system I need to use Calibre custom columns and be able to export the books I want with this specific name format. I have yet to find a program other than calibre that would support this.
It would probably be smarter for me to reorganize my books at some point but I really like being able to basically drop a ton of books at once onto my reader using SFTP and as far as I can tell all common options rely on manually downloading the books, sending them directly to the reader or pulling them from their internal file storage in whatever form the application stores them...
I do like Audiobookshelf for the ability to add a book to multiple series, but the missing mass export functions stop me from switching