media: add natpmpc-helper sidecar for ProtonVPN port forwarding

Adds a lightweight Alpine sidecar that runs natpmpc against the ProtonVPN
NAT-PMP gateway (10.2.0.1) every 45s to maintain a forwarded port, then
updates qBittorrent's listen port via API. Without inbound port forwarding
peers can only be dialed out to, which severely limits download speeds on
a gigabit connection.
This commit is contained in:
Will Anderson
2026-04-11 08:21:37 -05:00
parent 615f455eff
commit fd08987e12
@@ -66,6 +66,44 @@ spec:
memory: 512Mi
cpu: 200m
# NAT-PMP helper — requests a forwarded port from ProtonVPN gateway every 45s
# and updates qBittorrent's listen port so peers can connect inbound
- name: natpmpc-helper
image: alpine:latest
command:
- sh
- -c
- |
apk add -q natpmpc curl 2>/dev/null
echo "Waiting for VPN and qBittorrent to start..."
sleep 30
while true; do
# Request port forwarding from ProtonVPN NAT-PMP gateway
OUT=$(natpmpc -a 0 0 udp 60 -g 10.2.0.1 2>&1)
PORT=$(echo "$OUT" | grep -oE 'Mapped public port [0-9]+' | grep -oE '[0-9]+$')
if [ -n "$PORT" ]; then
echo "$(date): Got forwarded port $PORT"
# Also request TCP mapping for the same port
natpmpc -a "$PORT" "$PORT" tcp 60 -g 10.2.0.1 >/dev/null 2>&1
# Update qBittorrent listen port
SID=$(curl -s -c /tmp/qbt.txt -X POST http://localhost:8080/api/v2/auth/login \
-d "username=admin&password=adminadmin" 2>/dev/null)
curl -s -b /tmp/qbt.txt -X POST http://localhost:8080/api/v2/app/setPreferences \
-d "{\"json\":{\"listen_port\":$PORT,\"random_port\":false}}" >/dev/null 2>&1
echo "$(date): qBittorrent listen port set to $PORT"
else
echo "$(date): NAT-PMP failed: $OUT"
fi
sleep 45
done
resources:
requests:
memory: 16Mi
cpu: 10m
limits:
memory: 32Mi
cpu: 50m
# qBittorrent — shares gluetun's network namespace, all traffic through VPN
- name: qbittorrent
image: lscr.io/linuxserver/qbittorrent:latest