Open tyvsmith opened 1 year ago
Try out charlocharlie/qbittorrent-port-forward-file:latest
I had to make a few changes to charlocharlie/qbittorrent-port-forward-file
to get it to work but my setup is working flawless now. Here's my compose for anyone else who stumbles on this looking for an answer:
services:
port-forward:
image: ceramicwhite/gluetun-port-forward-qbit-cron:latest
container_name: port-forward
restart: on-failure
environment:
- QBT_USERNAME=admin
- QBT_PASSWORD=adminadmin
- QBT_ADDR=http://gluetun:8080
- GTN_ADDR=http://gluetun:8000
depends_on:
- gluetun
- qbittorrent
gluetun:
container_name: gluetun
image: qmcgaw/gluetun
stop_grace_period: 1m
cap_add:
- net_admin
devices:
- /dev/net/tun:/dev/net/tun
environment:
- VPN_SERVICE_PROVIDER=custom
- VPN_PORT_FORWARDING_PROVIDER=<your port forwarding provider>
- VPN_PORT_FORWARDING=on
- VPN_TYPE=wireguard
- WIREGUARD_PRIVATE_KEY=<your private key>
- WIREGUARD_PUBLIC_KEY=<your public key>
- WIREGUARD_ADDRESSES=<your wireguard address>
- VPN_ENDPOINT_IP=<your vpn endpoint ip>
- VPN_ENDPOINT_PORT=<your vpn endpoint port>
ports:
- 6380:6380
- 4443:4443
- 8888:8888/tcp # HTTP proxy
- 8388:8388/tcp # Shadowsocks
- 8388:8388/udp # Shadowsocks
- 8080:8080 #qBittorrent
restart: unless-stopped
volumes:
- ./data/gluetun:/tmp/gluetun
qbittorrent:
image: linuxserver/qbittorrent:latest
container_name: qbittorrent
stop_grace_period: 1m
environment:
- PUID=1000
- PGID=1000
- TZ=America/Los_Angeles
- WEBUI_PORT=8080
volumes:
- ./data/qbittorrent/config:/config
- ./data/qbittorrent/downloads:/downloads
restart: unless-stopped
network_mode: "service:gluetun"
depends_on:
- gluetun
# swag:
# image: lscr.io/linuxserver/swag:latest
# container_name: swag
# stop_grace_period: 1m
# cap_add:
# - NET_ADMIN
# environment:
# - PUID=1000
# - PGID=1000
# - TZ=America/Los_Angeles
# - URL=
# - VALIDATION=dns
# - SUBDOMAINS=wildcard
# # CERTPROVIDER= #optional
# - DNSPLUGIN=cloudflare
# #- PROPAGATION= #optional
# - EMAIL=
# #- ONLY_SUBDOMAINS=false #optional
# - EXTRA_DOMAINS=
# - STAGING=false #optional
# - DOCKER_MODS=linuxserver/mods:swag-auto-reload
# volumes:
# - ./data/swag/config:/config
# ports:
# - 443:443
# - 80:80
# restart: unless-stopped
networks:
default:
name: swag_network
ipam:
driver: default
@ceramicwhite I have tried your workaround on my system. The container starts but the port does not update on qbittorrent. The output of the container reads [FATAL tini (8)] exec /app/entrypoint.sh failed: Exec format error. For some extra info, I have started the stack through portainer and the host is a raspberry pi 4 running dietpi
I recently forked claabs/qbittorrent-port-forward-file
to build a container that would retrieve gluetun's port via the control server instead of the forwarded_port file: mjmeli/qbittorrent-port-forward-gluetun-server. According to gluetun documentation, the forwarded port file will be deprecated in the v4.0.0 release. Perhaps you can give this a try, it has been working for me flawlessly. There is a sample docker-compose in the README.
I wrote a quick app to synchronize port changes with other services https://github.com/afiestas/gluetun-sync
if @qdm12 is interested I could try to merge the code as a new "loop" within gluetun.
+1 and subscribing to this issue
also @mjmeli , by using your docker-compose sample in the same docker-compose file as qbittorrent and gluetun, I get
the requested url returned error: 401 could not get current forwarded port from gluetun, exiting...
and when visiting gluetun's url, I have a prompt for a login/password and don't know what those creds could be, nor if I should specify them in your container
@FrenchGithubUser AFAIK, the control server does not have any authentication. I would double check you are using the correct port, for example you should be able to hit http://<gluetun IP>:<gluetun port>/v1/publicip/ip
. I don't see anything in the documentation about it having authentication either.
@mjmeli nvm, the variable HTTP_CONTROL_SERVER_ADDRESS
was not set and the relevant port not forwarded in the docker-compose file
I'm confused, how are people successfully using dynamically allocated port forwarding? In the typical setup (e.g. a gluetun
service and a qbittorrent
service which uses the gluetun network, you would need not just to update the forwarded port in qbittorrent, but also expose that port in the gluetun service. But you don't know the port until the container has started, and it isn't possible to update the port mapping of a running Docker container. So the only way seems to be to have gluetun running inside the same container as your application?
@FrenchGithubUser
The port forwarding is handled through the VPN tunnel itself, and the process inside the container can adjust to use whatever port has been assigned by the VPN service provider. This doesn't require a change to the Docker container's port mappings, because the port that's being forwarded is not directly exposed on the host; instead, it's routed through the VPN connection, which Gluetun manages.
I ended up using another container that was made for gluetun and qbittorrent
+1 for this to be implemented as a native gluetun feature
Any updates on this? Would be a nice feature to have natively.
Here's my hands-off solution:
I'm Ansible, but this here uses no Ansible features, so it should easy to create a docker-compose from it:
- name: Create vpn container
community.general.docker_container:
container_default_behavior: "no_defaults"
name: vpn
image: qmcgaw/gluetun:latest
restart_policy: always
capabilities:
- NET_ADMIN # Required
devices:
- /dev/net/tun # not sure why required, works without, but it's in the instructions
env:
# ...
VPN_PORT_FORWARDING: "on"
mounts:
- type: bind
source: /containers/gluetun/tmp/gluetun
target: /tmp/gluetun
labels:
"traefik.enable": "true"
# ...
ports: []
networks:
- name: bridge
- name: Create qbittorrent container
community.general.docker_container:
container_default_behavior: "no_defaults"
name: qbittorrent
image: ghcr.io/linuxserver/qbittorrent:latest
restart_policy: always
network_mode: container:vpn
env:
# ...
mounts:
- type: bind
source: /containers/qbittorrent/config
target: /config
# this mounts the gluetun output into our container
- type: bind
source: /containers/gluetun/tmp/gluetun
target: /tmp/gluetun
- type: bind
source: /containers/qbittorrent/custom-services.d
target: /custom-services.d
- type: bind
source: /downloads
target: /downloads
The following script sits in /containers/qbittorrent/custom-services.d/update-forwarded-port.sh
. It is responsible for reading the forwarded_port
every DEFAULT_SLEEP
and update qBittorrent if it changed. It asks the port every DEFAULT_SLEEP
and if it changed, sends the update. We could blindly invoke the change port API every time, but I'm not sure how qBittorrent handles it if they don't change.
#!/usr/bin/with-contenv bash
# Change me
FILE=/tmp/gluetun/forwarded_port
# every minute
DEFAULT_SLEEP=60
while :; do
SLEEP=$DEFAULT_SLEEP
PORT=$(curl --silent --request GET --url "http://localhost:8080/api/v2/app/preferences" | jq ".listen_port")
NEW_PORT=$(cat $FILE)
if [[ "" == "$NEW_PORT" ]]; then
echo "No port in file or file not found?"
# retry faster
SLEEP=10
elif [[ "" == "$PORT" ]]; then
echo "API did not respond?"
# retry faster
SLEEP=10
elif [[ "$PORT" == "$NEW_PORT" ]]; then
echo "Ports did not change"
else
echo "Ports changed: old: $PORT, new: $NEW_PORT"
echo "Trying to update port via API"
curl \
--silent \
--request POST \
--url "http://localhost:8080/api/v2/app/setPreferences" \
--data "json={\"listen_port\": $NEW_PORT}"
if [[ $? -eq 0 ]]; then
echo "Port updated successfully"
PORT=$NEW_PORT
else
echo "Error updating port"
fi
fi
echo "Sleeping for $SLEEP, retrying afterwards"
sleep $SLEEP
done
Make sure qBittorrent allows for unauthenticated API calls from localhost, or add in your own auth in the curl
call.
For people who use Linuxserver's qbittorent image, i've made a docker mod to do just that : https://github.com/t-anc/GSP-Qbittorent-Gluetun-sync-port-mod
Just read the disclaimer in the README ;)
EDIT : It now also works with qBittorrent's images that are not Linuxserver.
For people who use Linuxserver's qbittorent image, i've made a docker mod to do just that : https://github.com/t-anc/GSP-Qbittorent-Gluetun-sync-port-mod
Just read the disclaimer in the README ;)
Thanks for this, it's the cleanest way of doing it and work perfectly.. Good job!
I've just found this thread and mjmeli/qbittorrent-port-forward-gluetun-server does the job.
But before arriving here, I coded a python daemon that basically does the same : GeoffreyCoulaud/glueforward. Maybe the error handling is a bit better? Eh at least I can add to the discussion :laughing:
What's the feature 🧐
ProtonVPN and potentially other torrent clients assign a dynamically generated port on each connection, requiring the client to be updated.
There are several approaches on the internet to keep these in sync by running a cron to check for the port on the VPN container and hit the QBittorrent API. This approach seems pretty hacky and not reliable.
It would be preferred if there was a standardized set of hooks that could be utilized to update the clients with a new port, or even first-class integration.
Extra information and references
Example Sync Script for TrueCharts/TrueNAS using the QBIttorrent app which sidecars Gluetun