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

421 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Qbittorrent
description: 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](/img/serveex/qbit-vue.jpeg)
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.
Heres the system well set up:
![Picture](/img/serveex/qbit.svg)
## 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`:
```bash [Terminal]
mkdir -P /media/downloads
```
### Deploy the stack
Open Dockge, click on `compose`, and name the stack `seedbox`. Paste the following config:
```yaml [compose.yaml]
---
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
```yaml [compose.yaml]
---
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:
```bash [Terminal]
sudo docker run --rm qmcgaw/gluetun genkey
```
Note the key, then create the `/docker/gluetun` folder:
```bash [Terminal]
sudo mkdir /docker/gluetun
```
Create the `config.toml` file:
```bash [Terminal]
sudo nano /docker/gluetun/config.toml
```
Enter:
```toml [config.toml]
[[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`:
```properties [.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
**Startup logs will show a temporary password for `admin` user.**
See logs in [Dockge](/serveex/core/docker/#dockge) to retrieve it, or type this command in a terminal:
```bash [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](/serveex/security/tinyauth) or [Authentik](/serveex/advanced/authentik/). Otherwise, dont 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.
::note
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 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:
```yaml [compose.yaml]
---
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=""}
✨ __Terminal-free tip:__ use [File Browser Quantum](/serveex/files/file-browser-quantum) to edit files instead of using the terminal.
::
```bash [Terminal]
sudo nano /docker/swag/config/nginx/proxy-confs/seedbox.subdomain.conf
```
Paste the following config (check the port):
```nginx [seedbox.subdomain.conf]
## 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](/serveex/security/tinyauth)'s forward-auth check directly to `seedbox.subdomain.conf`, the same way as [the TinyAuth guide](/serveex/security/tinyauth#protecting-an-app-via-reverse-proxy):
```nginx [seedbox.subdomain.conf]{26-38,41-42}
## 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
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](/serveex/security/tinyauth#exposing-tinyauth-with-swag). 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](/serveex/advanced/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](/serveex/advanced/authentik#protecting-an-app-via-reverse-proxy).
::
And thats it! You now have a ready-to-use media center.
![Picture](/img/serveex/seed.svg)