--- navigation: true title: Qbittorrent main: fluid: false --- :ellipsis{left=0px width=40rem top=10rem blur=140px} # Qbittorrent ::alert{type="info"} 🎯 __Goals:__ - Install and configure Qbittorrent - Securely connect to the BitTorrent network using Gluetun and Proton VPN :: ![Picture](https://github.com/VueTorrent/VueTorrent/blob/master/public/screenshots/screenshot-desktop-dark-mode.jpeg?raw=true) To safely download your favorite media, we'll build a system using: - [Qbittorrent](https://github.com/linuxserver/docker-qbittorrent) as the BitTorrent client - [Proton VPN Plus](https://protonvpn.com/torrenting), 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](https://github.com/qdm12/gluetun) - [Qbittorrent port update](https://codeberg.org/TechnoSam/qbittorrent-gluetun-port-update) to automatically update the VPN port (which changes regularly). - The [VueTorrent](https://github.com/gabe565/linuxserver-mod-vuetorrent) mod for a modern and intuitive UI. Here’s the system we’ll set up: ![Picture](/img/serveex/qbit.svg) ## Configuration --- Folder structure ```console root β”œβ”€β”€ docker β”‚ └── seedbox β”‚ β”œβ”€β”€ qbittorrent β”‚ β”‚ └── config β”‚ β”œβ”€β”€ gluetun β”‚ β”œβ”€β”€ compose.yaml β”‚ └── .env β”‚ └── media #linked to Plex and Qbittorrent β”œβ”€β”€ downloads #generic downloads, selected in settings β”œβ”€β”€ movies #used for downloading movies └── tvseries #used for downloading TV shows ``` If not already done, create the `downloads` folder under `/media`: ```sh mkdir -P /media/downloads ``` Open Dockge, click on `compose`, and name the stack `seedbox`. Paste the following config: ```yaml services: qbit: image: ghcr.io/linuxserver/qbittorrent:latest container_name: qbittorrent restart: unless-stopped network_mode: service:gluetun mem_limit: 1g 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.40 container_name: gluetun restart: unless-stopped mem_limit: 1g 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 ``` ::alert{type="success"} ✨ __Tip:__ Add the Watchtower label in each container to automate updates ```yaml services: qbittorrent: #... labels: - com.centurylinklabs.watchtower.enable=true gluetun: #... labels: - com.centurylinklabs.watchtower.enable=true ``` :: 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. We’ve 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: ```shell sudo docker run --rm qmcgaw/gluetun genkey ``` Note the key, then create the `/docker/gluetun` folder: ```shell sudo mkdir /docker/gluetun ``` Create the `config.toml` file: ```shell sudo vi /docker/gluetun/config.toml ``` Press `i` to edit and enter: ```toml [[roles]] name = "t-anc/GSP-Qbittorent-Gluetun-sync-port-mod" routes = ["GET /v1/openvpn/portforwarded"] auth = "apikey" apikey = "your_key_here" # key you just generated ``` Press `Esc` then type `:x` to save and exit. In Dockge, fill in the variables in `.env`: ```properties 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` | ## Deployment --- Once done, deploy the container. ::alert{type="warning"} :::list{type="warning"} - **Startup logs will show a temporary password for `admin` user** ::: :: Login at `http://server-ip:5695` (or the port you set). ::alert{type="danger"} :::list{type="danger"} - __If login fails:__ check your firewall rules. ::: :: Change your username and password in the "webui" settings. 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 Plex can sync correctly (`/media/movies` or `/media/tvseries`). You can also automate this with categories and folders. ## Exposing the Web UI --- ::alert{type="warning"} :::list{type="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 [Authentik](/serveex/security/authentik/). Otherwise, don’t expose it with SWAGβ€”use a VPN like [Wireguard](/serveex/security/wireguard) instead. ::: :: To start downloads from outside your home, without a VPN, you can expose the Qbittorrent web UI. ::alert{type="info"} :::list{type="info"} - We assume you have the subdomain `seedbox.mydomain.com` with a `CNAME` pointing to `mydomain.com` in [DNS zone](/general/networking/dns). And that port `443` on your router is forwarded to your server in [NAT rules](/general/networking/nat), unless you’re using Cloudflare Zero Trust. ::: :: In Dockge, edit the SWAG compose file and add Gluetun’s network: ```yaml services: swag: container_name: # ... # ... networks: # ... - seedbox networks: # ... seedbox: name: seedbox_default external: true ``` Click "Deploy" and wait for SWAG to fully initialize. ::alert{type="info"} :::list{type="info"} - We assume the network name is `seedbox_default`. You can confirm by checking the SWAG dashboard at http://server-ip:81. ::: :: Now create/edit `seedbox.subdomain.conf`. ::alert{type="success"} ✨ __Terminal-free tip:__ use [File Browser](/serveex/files/file-browser) to edit files instead of using the terminal. :: ```shell sudo vi /docker/swag/config/nginx/proxy-confs/seedbox.subdomain.conf ``` Press `i` and paste the following config (check the port): ```nginx ## 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; } } ``` ::alert{type="success"} ✨ You can secure this app with Authentik by uncommenting the `authentik-server.conf` and `authentik-location.conf` lines. Don’t forget to [create an app and provider in Authentik](/serveex/security/authentik#protecting-an-app-via-reverse-proxy). :: Press `Esc`, type `:x` to save and quit. Wait a few minutes, then go to `https://seedbox.mydomain.com`β€”you should land on the Qbittorrent interface. And that’s it! You now have a ready-to-use media center. ![Picture](/img/serveex/seed.svg)