---
title: Qbittorrent
description: Installer qBittorrent avec Gluetun et ProtonVPN pour télécharger des torrents de manière sécurisée derrière un VPN sur votre serveur auto-hébergé.
---


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

![Picture](/img/serveex/qbit-vue.jpeg)

Afin de télécharger vos media favoris en toute sécurité, nous allons monter un système à base de :

- [Qbittorent](https://github.com/linuxserver/docker-qbittorrent) comme logiciel de téléchargement bittorent
- [Proton VPN Plus](https://protonvpn.com/torrenting), VPN pour sécuriser vos échanges, auquel vous devez souscrire (il y a de nombreux codes promo) pour accéder au protocole Bittorent, mais vous pouvez également en choisir un autre, à condition qu'il propose le protocole bittorent.
- [Gluetun](https://github.com/qdm12/gluetun)
- [Qbittorrent port update](https://codeberg.org/TechnoSam/qbittorrent-gluetun-port-update) pour mettre automatiquement à jour le port de votre VPN (qui change régulièrement).
- Et le mode [vuetorrent](https://github.com/gabe565/linuxserver-mod-vuetorrent) pour une interface moderne et intuitive.

Nous monterons ici le système ci-dessous :

![Picture](/img/serveex/qbit.svg)

## Configuration

::file-tree
---
tree:
  /:
    - srv:
      - docker:
        - seedbox:
          - qbittorrent:
            - config/
          - gluetun/
          - compose.yaml
          - .env
    - "media # relié à Jellyfin et Qbittorrent":
      - "downloads/ # téléchargements génériques, choisis dans les réglages"
      - "movies/ # utilisé pour télécharger les films"
      - "tvseries/ # utilisé pour télécharger les séries"
---
::

::steps{level="3"}
### Créer les dossiers média

Si ce n'est pas déjà fait, créez le dossier `downloads` dans `/media` :

```bash [Terminal]
mkdir -P /media/downloads
```

### Déployer la stack

Ouvrez Dockge, cliquez sur `compose`, et nommez la stack `seedbox`. Collez la configuration suivante :

```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:
      - /srv/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:
      - /srv/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=""}
✨ __Astuce :__ ajoutez le label Watchtower dans chaque conteneur pour automatiser les mises à jour

```yaml [compose.yaml]
---
services:
  qbittorrent:
    #...
    labels:
      - com.centurylinklabs.watchtower.enable=true
  gluetun:
    #...
    labels:
      - com.centurylinklabs.watchtower.enable=true
```
::

### Configurer la mise à jour du port de téléchargement

Avant de renseigner le `.env` dans Dockge, configurons la mise à jour du port de téléchargement. Proton et la plupart des VPN font tourner le port de redirection, qui doit être communiqué à Qbittorrent.

Nous avons ajouté le mod `ghcr.io/t-anc/gsp-qbittorent-gluetun-sync-port-mod` au conteneur.

Il faut maintenant permettre au mod de récupérer les informations de Gluetun, qui n'autorise qu'une communication chiffrée via son API.

Ouvrez un terminal pour générer la clé d'authentification :

```bash [Terminal]
sudo docker run --rm qmcgaw/gluetun genkey
```

Notez la clé, puis créez le dossier `/srv/docker/gluetun` :

```bash [Terminal]
sudo mkdir /srv/docker/gluetun
```

Créez le fichier `config.toml` :

```bash [Terminal]
sudo nano /srv/docker/gluetun/config.toml
```

Saisissez :

```toml [config.toml]
[[roles]]
name = "t-anc/GSP-Qbittorent-Gluetun-sync-port-mod"
routes = ["GET /v1/portforward"]
auth = "apikey"
apikey = "votre_cle_ici" # la clé que vous venez de générer
```

Appuyez sur :kbd{value="Ctrl+O"}, puis :kbd{value="Enter"} pour enregistrer, et :kbd{value="Ctrl+X"} pour quitter.

### Renseigner vos variables d'environnement

Dans Dockge, renseignez les variables du `.env` :

```properties [.env]
PUID=
GUID=
UI_PORT=
PR_KEY=
GSP_KEY= # la clé générée et saisie dans config.toml
ID=
PW=
```

Détail :

| Variable   | Description | Exemple |
|------------|-------------|---------|
| `PUID`     | ID utilisateur (`id votreutilisateur`) | `1000` |
| `GUID`     | ID de groupe (`id votreutilisateur`) | `1000` |
| `UI_PORT`  | Port d'accès à l'interface web | `5695` |
| `PR_KEY`   | Clé privée fournie par Proton | `buKsjNHLyzKMM1qYnzOy4s7SHfly` |
| `GSP_KEY`  | Clé générée pour la mise à jour du port | `MnBa47MeVmk7xiv` |
| `ID`       | Identifiant de connexion à l'interface Qbittorrent | `user` |
| `PW`       | Mot de passe de l'interface Qbittorrent | `password` |

### Terminé !
::

## Déploiement

::steps{level="3"}
### Déployer le conteneur

Une fois fait, déployez le conteneur.

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

**Les logs de démarrage affichent un mot de passe temporaire pour l'utilisateur `admin`.**
Consultez les logs dans **Dockge** pour le récupérer, ou tapez cette commande dans un terminal :
```bash [Terminal]
docker logs qbittorrent 2>&1 | grep -i "temporary password"
```
::

### Se connecter et sécuriser son compte

Connectez-vous sur `http://ipduserveur:5695` (ou le port que vous avez défini).

::caution

__Si la connexion échoue :__ vérifiez les règles de votre pare-feu.
::

Changez votre identifiant et votre mot de passe dans les réglages « webui ».

### Terminé !
::

C'est terminé ! Dans les réglages de Qbittorrent, section « Téléchargements », définissez `/media/downloads` comme dossier par défaut.

Lors de l'ajout d'un téléchargement, pensez à choisir le bon dossier pour que Jellyfin se synchronise correctement (`/media/movies` ou `/media/tvseries`). Vous pouvez aussi automatiser cela avec des catégories et des dossiers.

## Exposer la webui

::warning

Qbittorrent ne gère pas l'authentification multifacteur. L'exposer sur internet peut mettre votre système en danger. Ne le faites que si vous utilisez du MFA via [TinyAuth](/serveex/security/tinyauth) ou [Authentik](/serveex/advanced/authentik/). Sinon, ne l'exposez pas avec SWAG. Utilisez plutôt un VPN comme [Wireguard](/serveex/core/wireguard).
::

Pour lancer des téléchargements depuis l'extérieur, sans VPN, vous pouvez exposer l'interface web de Qbittorrent.

::note

Nous partons du principe que vous avez le sous-domaine `seedbox.mondomaine.fr` avec un `CNAME` pointant vers `mondomaine.fr` dans la [zone DNS](/general/networking/dns). Et que le port `443` de votre box est redirigé vers votre serveur dans les [règles NAT](/general/networking/nat), à moins d'utiliser Cloudflare Zero Trust.
::

::steps{level="3"}
### Ajouter le réseau de Gluetun à SWAG

Dans Dockge, modifiez le fichier compose de SWAG et ajoutez le réseau de Gluetun :

```yaml [compose.yaml]
---
services:
  swag:
    container_name: # ...
    # ...
    networks:
      # ...
      - seedbox

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

Cliquez sur « Deploy » et attendez que SWAG soit complètement initialisé.

::note

Nous partons du principe que le nom du réseau est `seedbox_default`. Vous pouvez le confirmer en consultant le tableau de bord de SWAG sur http://ipduserveur:81.
::

### Créer le fichier subdomain.conf

Créez ou modifiez maintenant `seedbox.subdomain.conf`.

::tip{icon="" to="/serveex/files/file-browser-quantum"}
✨ __Astuce pour les allergiques au terminal :__ utilisez **File Browser Quantum** pour modifier les fichiers plutôt que le terminal.
::

```bash [Terminal]
sudo nano /srv/docker/swag/config/nginx/proxy-confs/seedbox.subdomain.conf
```

Collez la configuration suivante (vérifiez le 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;

    }
}
```

Appuyez sur :kbd{value="Ctrl+O"}, puis :kbd{value="Enter"} pour enregistrer, et :kbd{value="Ctrl+X"} pour quitter.

### Terminé !
::

Attendez quelques minutes, puis allez sur `https://seedbox.mondomaine.fr`. Vous devriez arriver sur l'interface de Qbittorrent.

## Protéger Qbittorrent avec TinyAuth
Ajoutez la vérification forward-auth de [TinyAuth](/serveex/security/tinyauth) directement dans `seedbox.subdomain.conf`, de la même façon que dans [le tutoriel TinyAuth](/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.mondomaine.fr/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"}

Le bloc `location /tinyauth` s'exécute dans le conteneur de SWAG lui-même, SWAG doit donc être sur le réseau Docker de TinyAuth pour le joindre par son nom (`tinyauth` ici). Cela devrait déjà être en place depuis **l'exposition de TinyAuth**. Si vous rencontrez une erreur, revérifiez que le fichier compose de SWAG a toujours ce réseau rattaché.
::

::tip{icon=""}
✨ Vous pouvez sécuriser cette application avec [Authentik](/serveex/advanced/authentik) plutôt que TinyAuth, en décommentant les lignes `authentik-server.conf` et `authentik-location.conf`. N'oubliez pas de [créer une application et un provider dans Authentik](/serveex/advanced/authentik#protecting-an-app-via-reverse-proxy).
::

Et voilà ! Vous avez maintenant un media center prêt à l'emploi.

![Picture](/img/serveex/seed.svg)
