Files
docudjeex/content/en/3.serveex/5.media/2.qbittorrent.md
T

12 KiB
Raw Blame History

title, description
title description
Qbittorrent Install qBittorrent with Gluetun and ProtonVPN to download torrents securely behind a VPN on your self-hosted server.

:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}

Picture

To safely download your favorite media, we'll build a system using:

  • Qbittorrent as the BitTorrent client
  • Proton VPN Plus, a VPN to secure your traffic. You need a subscription (promos available) to access the BitTorrent protocol. You can also use another VPN as long as it supports BitTorrent.
  • Gluetun
  • Qbittorrent port update to automatically update the VPN port (which changes regularly).
  • The VueTorrent mod for a modern and intuitive UI.

Heres the system well set up:

Picture

Configuration

::file-tree

tree: /: - docker: - seedbox: - qbittorrent: - config/ - gluetun/ - compose.yaml - .env - "media # linked to Jellyfin and Qbittorrent": - "downloads/ # generic downloads, selected in settings" - "movies/ # used for downloading movies" - "tvseries/ # used for downloading TV shows"

::

::steps{level="3"}

Create the media folders

If not already done, create the downloads folder under /media:

mkdir -P /media/downloads

Deploy the stack

Open Dockge, click on compose, and name the stack seedbox. Paste the following config:

---
services:
  qbit:
    image: ghcr.io/linuxserver/qbittorrent:libtorrentv1
    container_name: qbittorrent
    restart: unless-stopped
    network_mode: service:gluetun
    mem_limit: 4g
    environment:
      - DOCKER_MODS=ghcr.io/gabe565/linuxserver-mod-vuetorrent|ghcr.io/t-anc/gsp-qbittorent-gluetun-sync-port-mod:main
      - TZ=Europe/Paris
      - PUID=${PUID}
      - PGID=${GUID}
      - WEBUI_PORT=${UI_PORT}
      - GSP_GTN_API_KEY=${GSP_KEY}
      - GSP_QBT_USERNAME=${ID}
      - GSP_QBT_PASSWORD=${PW}
    volumes:
      - /docker/seedbox/qbittorrent/config:/config
      - /media:/media
    depends_on:
      - gluetun

  gluetun:
    image: qmcgaw/gluetun:v3.41.3
    container_name: gluetun
    restart: unless-stopped
    mem_limit: 4g
    volumes:
      - /docker/gluetun/config.toml:/gluetun/auth/config.toml:ro
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - ${UI_PORT}:5695 # Port de la web-ui
      - 8000:8000 # Port de controle de Gluetun
    cap_add:
      - NET_ADMIN
    environment:
      - TZ=Europe/Paris
      - VPN_SERVICE_PROVIDER=protonvpn
      - VPN_PORT_FORWARDING=on
      - VPN_PORT_FORWARDING_PROVIDER=protonvpn
      - VPN_TYPE=wireguard
      - WIREGUARD_PRIVATE_KEY=${PR_KEY}
      - SERVER_COUNTRIES=France
      - PORT_FORWARD_ONLY=on

::tip{icon=""} Tip: Add the Watchtower label in each container to automate updates

---
services:
  qbittorrent:
    #...
    labels:
      - com.centurylinklabs.watchtower.enable=true
  gluetun:
    #...
    labels:
      - com.centurylinklabs.watchtower.enable=true

::

Configure the download port update

Before editing the .env in Dockge, let's configure the download port update. Proton and most VPNs rotate the forwarding port, which must be communicated to Qbittorrent.

Weve added the mod ghcr.io/t-anc/gsp-qbittorent-gluetun-sync-port-mod to the container.

We now need to allow the mod to fetch info from Gluetun, which only allows encrypted communication via its API.

Open a terminal to generate the authentication key:

sudo docker run --rm qmcgaw/gluetun genkey

Note the key, then create the /docker/gluetun folder:

sudo mkdir /docker/gluetun

Create the config.toml file:

sudo nano /docker/gluetun/config.toml

Enter:

[[roles]]
name = "t-anc/GSP-Qbittorent-Gluetun-sync-port-mod"
routes = ["GET /v1/portforward"]
auth = "apikey"
apikey = "your_key_here" # key you just generated

Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit.

Set your environment variables

In Dockge, fill in the variables in .env:

PUID=
GUID=
UI_PORT=
PR_KEY=
GSP_KEY= # the key you generated and entered in config.toml
ID=
PW=

Detailed info:

Variable Description Example
PUID User ID (id yourusername) 1000
GUID Group ID (id yourusername) 1000
UI_PORT Port for accessing the web UI 5695
PR_KEY Private key from Proton buKsjNHLyzKMM1qYnzOy4s7SHfly
GSP_KEY Key you generated for port update MnBa47MeVmk7xiv
ID Qbittorrent UI login username user
PW Qbittorrent UI password password

Done !

::

Deployment

::steps{level="3"}

Deploy the container

Once done, deploy the container.

::note{to="/serveex/core/docker/#dockge"}

Startup logs will show a temporary password for admin user. See logs in Dockge to retrieve it, or type this command in a terminal:

docker logs qbittorrent 2>&1 | grep -i "temporary password"

::

Log in and secure your account

Login at http://server-ip:5695 (or the port you set).

::caution

If login fails: check your firewall rules. ::

Change your username and password in the "webui" settings.

Done !

::

You're done! In Qbittorrent settings, under "Downloads", set /media/downloads as the default folder.

When adding a download, remember to select the proper directory so Jellyfin can sync correctly (/media/movies or /media/tvseries). You can also automate this with categories and folders.

Exposing the Web UI

::warning

Qbittorrent does not support multi-factor authentication. Exposing it to the internet may put your system at risk. Only do this if you use MFA via TinyAuth or Authentik. Otherwise, dont expose it with SWAG. Use a VPN like Wireguard instead. ::

To start downloads from outside your home, without a VPN, you can expose the Qbittorrent web UI.

::note

We assume you have the subdomain seedbox.mydomain.com with a CNAME pointing to mydomain.com in DNS zone. And that port 443 on your router is forwarded to your server in NAT rules, unless youre using Cloudflare Zero Trust. ::

::steps{level="3"}

Add Gluetun's network to SWAG

In Dockge, edit the SWAG compose file and add Gluetuns network:

---
services:
  swag:
    container_name: # ...
    # ...
    networks:
      # ...
      - seedbox

networks:
  # ...
  seedbox:
    name: seedbox_default
    external: true

Click "Deploy" and wait for SWAG to fully initialize.

::note

We assume the network name is seedbox_default. You can confirm by checking the SWAG dashboard at http://server-ip:81. ::

Create the subdomain.conf file

Now create/edit seedbox.subdomain.conf.

::tip{icon="" to="/serveex/files/file-browser-quantum"} Terminal-free tip: use File Browser Quantum to edit files instead of using the terminal. ::

sudo nano /docker/swag/config/nginx/proxy-confs/seedbox.subdomain.conf

Paste the following config (check the port):

## Version 2023/12/19

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name seedbox.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    #if ($lan-ip = yes) { set $geo-whitelist yes; }
    #if ($geo-whitelist = no) { return 404; }
    if ($geo-blacklist = no) { return 404; }

    # enable for ldap auth (requires ldap-location.conf in the location block)
    #include /config/nginx/ldap-server.conf;

    # enable for Authelia (requires authelia-location.conf in the location block)
    #include /config/nginx/authelia-server.conf;

    # enable for Authentik (requires authentik-location.conf in the location block)
    #include /config/nginx/authentik-server.conf;

    location / {
        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        # enable for ldap auth (requires ldap-server.conf in the server block)
        #include /config/nginx/ldap-location.conf;

        # enable for Authelia (requires authelia-server.conf in the server block)
        #include /config/nginx/authelia-location.conf;

        # enable for Authentik (requires authentik-server.conf in the server block)
        #include /config/nginx/authentik-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app gluetun;
        set $upstream_port 5555;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

    }
}

Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit.

Done !

::

Wait a few minutes, then go to https://seedbox.mydomain.com. You should land on the Qbittorrent interface.

Protecting Qbittorrent with TinyAuth

Add TinyAuth's forward-auth check directly to seedbox.subdomain.conf, the same way as the TinyAuth guide:

## Version 2023/12/19

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name seedbox.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    #if ($lan-ip = yes) { set $geo-whitelist yes; }
    #if ($geo-whitelist = no) { return 404; }
    if ($geo-blacklist = no) { return 404; }

    # enable for ldap auth (requires ldap-location.conf in the location block)
    #include /config/nginx/ldap-server.conf;

    # enable for Authelia (requires authelia-location.conf in the location block)
    #include /config/nginx/authelia-server.conf;

    # enable for Authentik (requires authentik-location.conf in the location block)
    #include /config/nginx/authentik-server.conf;

    location /tinyauth {
        internal;
        proxy_pass http://tinyauth:3000/api/auth/nginx;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Uri $request_uri;
    }

    location @tinyauth_login {
        return 302 https://tinyauth.mydomain.com/login?redirect_uri=$scheme://$http_host$request_uri;
    }

    location / {
        auth_request /tinyauth;
        error_page 401 = @tinyauth_login;

        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        # enable for ldap auth (requires ldap-server.conf in the server block)
        #include /config/nginx/ldap-location.conf;

        # enable for Authelia (requires authelia-server.conf in the server block)
        #include /config/nginx/authelia-location.conf;

        # enable for Authentik (requires authentik-server.conf in the server block)
        #include /config/nginx/authentik-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app gluetun;
        set $upstream_port 5555;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

    }
}

::note{to="/serveex/security/tinyauth#exposing-tinyauth-with-swag"}

The location /tinyauth block runs inside SWAG's own container, so SWAG needs to be on TinyAuth's Docker network to reach it by name (tinyauth here). This should already be set up from exposing TinyAuth itself. If you run into an error, double-check SWAG's compose file still has that network attached. ::

::tip{icon=""} You can secure this app with Authentik instead of TinyAuth by uncommenting the authentik-server.conf and authentik-location.conf lines. Dont forget to create an app and provider in Authentik. ::

And thats it! You now have a ready-to-use media center.

Picture