Skip to content
This repository has been archived by the owner on Jul 16, 2023. It is now read-only.

Added a process running check #161

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ RUN apt update \
&& apt purge -y \
build-essential \
ca-certificates \
curl \
curl \
git \
jq \
libssl-dev \
Expand All @@ -164,23 +164,47 @@ RUN apt update \
/tmp/* \
/var/tmp/*

# Download and extract VueTorrent
RUN apt update \
&& apt upgrade -y \
&& apt install -y --no-install-recommends \
ca-certificates \
curl \
unzip \
&& VUETORRENT_RELEASE=v2.7.1 \
&& curl -o /config/vuetorrent.zip -L "https://github.com/VueTorrent/VueTorrent/releases/download/${VUETORRENT_RELEASE}/vuetorrent.zip" \
&& cd /config \
&& unzip vuetorrent.zip \
&& apt purge -y \
ca-certificates \
curl \
&& apt-get clean \
&& apt --purge autoremove -y \
&& rm -rf \
/var/lib/apt/lists/* \
/tmp/* \
/var/tmp/*

# Install WireGuard and some other dependencies some of the scripts in the container rely on.
RUN echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable-wireguard.list \
&& printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable \
&& apt update \
&& apt install -y --no-install-recommends \
ca-certificates \
curl \
dos2unix \
inetutils-ping \
ipcalc \
iptables \
jq \
kmod \
libqt5network5 \
libqt5xml5 \
libqt5sql5 \
libssl1.1 \
moreutils \
net-tools \
natpmpc \
openresolv \
openvpn \
procps \
Expand All @@ -200,7 +224,6 @@ RUN echo "deb http://deb.debian.org/debian/ bullseye non-free" > /etc/apt/source
&& apt -y install --no-install-recommends \
unrar \
p7zip-full \
unzip \
zip \
&& apt-get clean \
&& apt --purge autoremove -y \
Expand Down
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ Docker container which runs the latest [qBittorrent](https://github.com/qbittorr
* Configurable UID and GID for config files and /downloads for qBittorrent
* Created with [Unraid](https://unraid.net/) in mind
* BitTorrent port 8999 exposed by default
* Automatically restarts the qBittorrent process in the event of it crashing.
* Adds VueTorrent (alternate web UI) which can be enabled (or not) by the user.
* Works with Proton VPN's port forward VPN servers to automatically enable forwarding in your container, and automatically sets the connection port in qBittorrent to match the forwarded port.

## Run container from Docker registry
The container is available from the Docker registry and this is the simplest way to get it
Expand All @@ -34,7 +37,7 @@ $ docker run -d \
--cap-add NET_ADMIN \
--sysctl "net.ipv4.conf.all.src_valid_mark=1" \
--restart unless-stopped \
dyonr/qbittorrentvpn
tenseiken/qbittorrentvpn:latest
```

## Docker Tags
Expand All @@ -57,7 +60,7 @@ $ docker run -d \
|`VPN_PASSWORD`| No | If username and password provided, configures ovpn file automatically |`VPN_PASSWORD=ac98df79ed7fb`||
|`LAN_NETWORK`| Yes (atleast one) | Comma delimited local Network's with CIDR notation |`LAN_NETWORK=192.168.0.0/24,10.10.0.0/24`||
|`LEGACY_IPTABLES`| No | Use `iptables (legacy)` instead of `iptables (nf_tables)` |`LEGACY_IPTABLES=yes`||
|`ENABLE_SSL`| No | Let the container handle SSL (yes/no)? |`ENABLE_SSL=yes`|`yes`|
|`ENABLE_SSL`| No | Let the container handle SSL (yes/no/ignore)? |`ENABLE_SSL=yes`|`ignore`|
|`NAME_SERVERS`| No | Comma delimited name servers |`NAME_SERVERS=1.1.1.1,1.0.0.1`|`1.1.1.1,1.0.0.1`|
|`PUID`| No | UID applied to /config files and /downloads |`PUID=99`|`99`|
|`PGID`| No | GID applied to /config files and /downloads |`PGID=100`|`100`|
Expand All @@ -69,6 +72,10 @@ $ docker run -d \
|`RESTART_CONTAINER`| No |Set to `no` to **disable** the automatic restart when the network is possibly down.|`RESTART_CONTAINER=yes`|`yes`|
|`INSTALL_PYTHON3`| No |Set this to `yes` to let the container install Python3.|`INSTALL_PYTHON3=yes`|`no`|
|`ADDITIONAL_PORTS`| No |Adding a comma delimited list of ports will allow these ports via the iptables script.|`ADDITIONAL_PORTS=1234,8112`||
|`ENABLEPROTONVPNPORTFWD` | No | Enables Proton VPN port forwarding logic. 1 to enable, 0 to disable. | `ENABLEPROTONVPNPORTFWD=1` | 0 |
|`WEBUI_URL` | Only if port fwd enabled | Allows the script to use the WebUI API to set the forwarded port automatically. | `WEBUI_URL=https://webui.domain.com` / `WEBUI_URL=http://192.168.1.17` ||
|`WEBUI_USER` | Only if port fwd enabled | Allows the script to use the WebUI API to set the forwarded port automatically. | `WEBUI_USER=admin` ||
|`WEBUI_PASS` | Only if port fwd enabled | Allows the script to use the WebUI API to set the forwarded port automatically. | `WEBUI_PASS=adminadmin` ||

## Volumes
| Volume | Required | Function | Example |
Expand Down Expand Up @@ -104,6 +111,17 @@ If you do not do this, the container will keep on stopping with the error `RTNET
Since I do not have IPv6, I am did not test.
Thanks to [mchangrh](https://github.com/mchangrh) / [Issue #49](https://github.com/DyonR/docker-qbittorrentvpn/issues/49)

## Proton VPN Port Forwarding with Wireguard
If you use Proton VPN as your VPN provider, they offer a feature called port forwarding that will improve your connectability from peers in the swarm. This works by running a script on a loop in the background that periodically refreshes your port forward. That's necessary because they have to be set with an expiration time, even though we don't want it to expire while our client is running. We don't get to choose the port that's going to be forwarded (that is handled by Proton VPN), and it can change periodically, so we need to be able to change the listen port in qBittorrent in the event of a change. In order to update the listen port in qBittorrent, an authenticated API call to your local qBittorrent instance is required. If you want to have this functionality enabled, you can do the following:

- Use your Proton VPN account to acquire a Wireguard config file for one of their port-forwarding-enabled servers. These are paid servers--the free ones do not support it. Save this config file as wg0.conf in the Wireguard config directory just like you would any other Wireguard config file.
- Set the `ENABLEPROTONVPNPORTFWD` environment variable in your container to 1.
- Set the `WEBUI_URL` environment variable in your container to the URL you use to access your qBittorrent web UI. This can be the local IP (ex: http://192.168.1.17) or a public URL if you have one (ex: https://qbittorrent.mydomain.com). As long as the container can reach this URL over its network, it's fine.
- Set the `WEBUI_USER` environment variable in your container to the username you use to authenticate with your qBittorrent web UI.
- Set the `WEBUI_PASS` environment variable in your container to the password you use to authenticate with your qBittorrent web UI.

With all of that set up, port forwarding will be automatically established for you, and the listen port in qBittorrent will be set automatically.

# How to use OpenVPN
The container will fail to boot if `VPN_ENABLED` is set and there is no valid .ovpn file present in the /config/openvpn directory. Drop a .ovpn file from your VPN provider into /config/openvpn (if necessary with additional files like certificates) and start the container again. You may need to edit the ovpn configuration file to load your VPN credentials from a file by setting `auth-user-pass`.

Expand Down
4 changes: 4 additions & 0 deletions qbittorrent/iptables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,8 @@ echo "--------------------"
iptables -S
echo "--------------------"

# start the NAT-PMP port forward loop
if [[ $ENABLEPROTONVPNPORTFWD -eq 1 ]] ; then
nohup /etc/qbittorrent/portfwd.sh > /dev/null 2>&1 &
fi
exec /bin/bash /etc/qbittorrent/start.sh
9 changes: 9 additions & 0 deletions qbittorrent/portfwd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

port=$(natpmpc -a 1 0 udp 60 -g 10.2.0.1 | grep "public port" | awk '/Mapped public port/ {print $4}')

# find and replace "Session\Port=.*" in /config/qBittorrent/config/qBittorrent.conf with $port
sed -i -r "s/^(Session\\\Port=).*/\1$port/" /config/qBittorrent/config/qBittorrent.conf

# run the port forward loop.
while true ; do date ; natpmpc -a 1 0 udp 60 -g 10.2.0.1 && natpmpc -a 1 0 tcp 60 -g 10.2.0.1 || { echo -e "ERROR with natpmpc command \a" ; break ; } ; sleep 45 ; done
33 changes: 31 additions & 2 deletions qbittorrent/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ fi
# Set the correct rights accordingly to the PUID and PGID on /config/qBittorrent
chown -R ${PUID}:${PGID} /config/qBittorrent

##Disabling this because the downloads folder is my whole NAS and file ownerships are already managed by ACL.
# Set the rights on the /downloads folder
find /downloads -not -user ${PUID} -execdir chown ${PUID}:${PGID} {} \+
#find /downloads -not -user ${PUID} -execdir chown ${PUID}:${PGID} {} \+

# Check if qBittorrent.conf exists, if not, copy the template over
if [ ! -e /config/qBittorrent/config/qBittorrent.conf ]; then
Expand Down Expand Up @@ -63,10 +64,12 @@ if [[ ${ENABLE_SSL} == "1" || ${ENABLE_SSL} == "true" || ${ENABLE_SSL} == "yes"
echo "[WARNING] /config/qBittorrent/config/qBittorrent.conf doesn't have the WebUI\HTTPS\Enabled loaded. Added it to the config." | ts '%Y-%m-%d %H:%M:%.S'
echo 'WebUI\HTTPS\Enabled=true' >> "/config/qBittorrent/config/qBittorrent.conf"
fi
else
elif [[ ${ENABLE_SSL} == "0" || ${ENABLE_SSL} == "false" || ${ENABLE_SSL} == "no" ]]; then
echo "[WARNING] ENABLE_SSL is set to '${ENABLE_SSL}', SSL is not enabled. This could cause issues with logging if other apps use the same Cookie name (SID)." | ts '%Y-%m-%d %H:%M:%.S'
echo "[WARNING] Removing the SSL configuration from the config file..." | ts '%Y-%m-%d %H:%M:%.S'
sed -i '/^WebUI\\HTTPS*/d' "/config/qBittorrent/config/qBittorrent.conf"
else
echo "[WARNING] ENABLE_SSL is set to '${ENABLE_SSL}', SSL config ignored. No changes made." | ts '%Y-%m-%d %H:%M:%.S'
fi

# Check if the PGID exists, if not create the group with the name 'qbittorrent'
Expand Down Expand Up @@ -161,6 +164,13 @@ if [ -e /proc/$qbittorrentpid ]; then
echo "[INFO] HEALTH_CHECK_AMOUNT is set to ${HEALTH_CHECK_AMOUNT}" | ts '%Y-%m-%d %H:%M:%.S'

while true; do
# Confirm the process is still running, start it back up if it's not.
if ! ps -p $qbittorrentpid > /dev/null; then
echo "[ERROR] qBittorrent daemon is not running. Restarting..." | ts '%Y-%m-%d %H:%M:%.S'
/bin/bash /etc/qbittorrent/qbittorrent.init start
wait $!
qbittorrentpid=$(cat /var/run/qbittorrent.pid)
fi
# Ping uses both exit codes 1 and 2. Exit code 2 cannot be used for docker health checks, therefore we use this script to catch error code 2
ping -c ${HEALTH_CHECK_AMOUNT} $HOST > /dev/null 2>&1
STATUS=$?
Expand All @@ -175,6 +185,25 @@ if [ -e /proc/$qbittorrentpid ]; then
if [[ ${HEALTH_CHECK_SILENT,,} == "0" || ${HEALTH_CHECK_SILENT,,} == "false" || ${HEALTH_CHECK_SILENT,,} == "no" ]]; then
echo "[INFO] Network is up" | ts '%Y-%m-%d %H:%M:%.S'
fi

# Check the NAT port forward and update qBittorrent config if there is a change.
if [[ $ENABLEPROTONVPNPORTFWD -eq 1 ]] ; then
loginData="username=$WEBUI_USER&password=$WEBUI_PASS"
cookie=$(curl -i --silent --header "Referer: $WEBUI_URL" --data $loginData $WEBUI_URL/api/v2/auth/login | grep "set-cookie" | awk '/set-cookie:/ {print $2}' | sed 's/;//') > /dev/null 2>&1
if [[ $cookie ]]; then
setPort=$(curl --silent $WEBUI_URL/api/v2/app/preferences --cookie $cookie | jq '.listen_port') > /dev/null 2>&1
currentPort=$(natpmpc -a 1 0 udp 60 -g 10.2.0.1 | grep "public port" | awk '/Mapped public port/ {print $4}')
if [[ $setPort -ne $currentPort ]] ; then
portData="json={\"listen_port\":$currentPort}"
curl -i --silent --data $portData $WEBUI_URL/api/v2/app/setPreferences --cookie $cookie > /dev/null 2>&1
fi
curl --silent -X 'POST' "$WEBUI_URL/api/v2/auth/logout" -H 'accept: */*' -d '' --cookie $cookie > /dev/null 2>&1
else
echo "[WARNING] Unable to log into the web UI." | ts '%Y-%m-%d %H:%M:%.S'
fi
unset cookie
fi

sleep ${INTERVAL} &
# combine sleep background with wait so that the TERM trap above works
wait $!
Expand Down