Annexe 4 : Exemples Docker Compose

Cette annexe propose des fichiers de départ lisibles et copiables. Ils ne sont pas universels : adaptez surtout les chemins, les identifiants utilisateur, les ports, le réseau local et le fournisseur VPN à votre machine.

L’exemple principal vise une installation Linux classique avec Jellyfin. Sur Unraid, TrueNAS, Synology ou une seedbox, les mêmes conteneurs existent souvent via une interface graphique, mais les chemins et permissions changent.

Avant de copier

Les exemples utilisent /srv/servarr, un emplacement adapté à une installation Docker classique sous Ubuntu. Si vos données se trouvent sur un disque ou un pool monté séparément, le chemin peut par exemple devenir /mnt/storage/servarr. Sous Unraid, il prendra généralement la forme /mnt/user/....

Les exemples utilisent le dossier suivant :

/srv/servarr
├── appdata
└── data
    ├── downloads
    │   ├── torrents
    │   └── cross-seed
    └── library
        ├── movies
        └── series

La règle importante reste la même :

qBittorrent, Radarr et Sonarr doivent recevoir le même volume /data.

Vous utilisez un NAS ?
Sur Synology, Unraid, QNAP, TrueNAS ou UGREEN NAS, vous pouvez généralement créer les mêmes conteneurs depuis l’interface graphique de votre appareil, ou importer un fichier Docker Compose lorsque cette option est disponible. Les noms des menus et les chemins changent, mais le principe reste identique : conservez les configurations dans un dossier persistant, montez le même dossier de données en /data pour qBittorrent/Radarr/Sonarr, et adaptez les ports à ceux déjà utilisés sur votre NAS.

Créez un fichier .env à côté de votre fichier compose.yaml :

PUID=1000
PGID=1000
TZ=Europe/Paris
APPDATA=/srv/servarr/appdata
DATA=/srv/servarr/data
LAN_NETWORK=192.168.1.0/24
VPN_USER=identifiant_vpn
VPN_PASS=mot_de_passe_vpn

Le fichier .env n’est pas obligatoire : vous pouvez remplacer directement ${PUID}, ${PGID}, ${APPDATA}, ${DATA}, ${LAN_NETWORK}, ${VPN_USER} et ${VPN_PASS} par vos valeurs dans chaque conteneur. Il évite simplement de répéter les mêmes chemins et réglages partout.

Sur Ubuntu ou une installation Docker en ligne de commande, ouvrez un terminal dans le dossier où se trouve votre fichier compose.yaml ainsi que votre éventuel fichier .env. Par exemple, si ces fichiers sont enregistrés dans /srv/servarr, rendez-vous d’abord dans ce dossier :

cd /srv/servarr

Lancez ensuite la commande suivante dans le terminal :

docker compose up -d

Docker lit le fichier compose.yaml présent dans le dossier courant, télécharge les images nécessaires et démarre les conteneurs en arrière-plan. L’option -d permet de récupérer immédiatement la main dans le terminal.

Commandes Docker utiles

Sur une installation Linux classique, les commandes suivantes se lancent depuis un terminal. Sur un NAS comme Synology, Unraid, QNAP, TrueNAS ou UGREEN NAS, vous pouvez souvent créer, démarrer et mettre à jour les conteneurs directement depuis l’interface web ; utilisez ces commandes seulement si votre interface le demande ou pour dépanner.

Les commandes docker compose ci-dessous doivent être lancées depuis le dossier qui contient votre fichier compose.yaml.

Gérer toute la stack

Action Commande
Démarrer les conteneurs docker compose up -d
Voir les conteneurs et leur état docker compose ps
Arrêter les conteneurs sans les supprimer docker compose stop
Redémarrer les conteneurs arrêtés docker compose start
Redémarrer toute la stack docker compose restart
Arrêter et supprimer les conteneurs docker compose down

docker compose down ne supprime pas vos fichiers de configuration ni vos médias si les volumes pointent bien vers vos dossiers sur la machine. N’ajoutez pas l’option -v sans comprendre son effet : elle peut supprimer des volumes Docker contenant des données.

Consulter les erreurs

Pour afficher les messages de toutes les applications :

docker compose logs -f

Pour suivre seulement une application, indiquez son nom de service, par exemple :

docker compose logs -f sonarr

Utilisez Ctrl+C pour quitter l’affichage des logs : cela n’arrête pas les conteneurs.

Redémarrer une seule application

Après avoir modifié un réglage ou si une application répond mal :

docker compose restart sonarr

Remplacez sonarr par radarr, prowlarr, qbittorrent, jellyfin ou seerr selon l’application concernée.

Mettre à jour les applications

Depuis le dossier du fichier compose.yaml :

docker compose pull
docker compose up -d

La première commande récupère les nouvelles images disponibles. La seconde recrée les conteneurs concernés en conservant leur configuration et leurs médias stockés dans les dossiers montés.

Vérifier Docker sur la machine

Ces commandes peuvent être lancées depuis n’importe quel dossier :

Action Commande
Vérifier que Docker est installé docker --version
Voir tous les conteneurs actifs docker ps
Voir aussi les conteneurs arrêtés docker ps -a
Voir l’espace disque utilisé par Docker docker system df

Un fichier YAML par application

Vous n’êtes pas obligé de placer toutes les applications dans un seul fichier compose.yaml. Vous pouvez créer un dossier docker-compose contenant un fichier YAML nommé par application, ce qui permet de les retrouver et de les gérer indépendamment.

Exemple d’organisation :

/srv/servarr/docker-compose
├── qbittorrent.yaml
├── prowlarr.yaml
├── radarr.yaml
├── sonarr.yaml
└── jellyfin.yaml

compose.yaml est le nom lu automatiquement par Docker Compose. Avec un fichier nommé radarr.yaml, précisez son nom avec l’option -f.

Pour démarrer uniquement Radarr, ouvrez un terminal dans le dossier docker-compose :

cd /srv/servarr/docker-compose
docker compose -f radarr.yaml up -d

Sur un NAS, cette séparation peut aussi se traduire par un projet ou un conteneur créé séparément dans l’interface web.

Garder les applications connectées

Avec plusieurs fichiers Compose, créez une seule fois un réseau commun :

docker network create servarr

Ajoutez ensuite cette partie à la fin de chaque fichier YAML :

networks:
  servarr:
    external: true

Et conservez dans chaque service :

    networks:
      - servarr

Ainsi, Radarr peut joindre qbittorrent ou prowlarr par leur nom de conteneur, même si les applications sont définies dans des fichiers différents.

Le réseau commun ne remplace pas les dossiers partagés : qBittorrent, Radarr et Sonarr doivent toujours monter le même volume en /data, par exemple :

    volumes:
      - ${DATA}:/data

Pour lancer plusieurs fichiers en même temps, ajoutez simplement plusieurs options -f :

docker compose -f qbittorrent.yaml -f prowlarr.yaml -f radarr.yaml -f sonarr.yaml -f jellyfin.yaml up -d

Un seul fichier ou plusieurs ?

Organisation Avantage principal Bon choix si…
Un seul compose.yaml Toute la stack se lance en une commande Vous débutez et voulez une installation simple à suivre
Un fichier YAML nommé par application Chaque conteneur est simple à retrouver et à gérer Votre NAS fonctionne par projets séparés ou vous préférez isoler les services

Exemple 1 : La base avec Jellyfin

Cet exemple contient qBittorrent sans VPN, Prowlarr, Radarr, Sonarr, Jellyfin et Seerr. Il permet de visualiser toute la stack ; avant d’utiliser le torrent, remplacez le service qBittorrent par l’exemple VPN suivant.

name: servarr

services:
  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
      - WEBUI_PORT=8080
    volumes:
      - ${APPDATA}/qbittorrent:/config
      - ${DATA}:/data
    ports:
      - "8080:8080"
      - "6881:6881"
      - "6881:6881/udp"
    restart: unless-stopped
    networks:
      - servarr

  prowlarr:
    image: lscr.io/linuxserver/prowlarr:latest
    container_name: prowlarr
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ${APPDATA}/prowlarr:/config
    ports:
      - "9696:9696"
    restart: unless-stopped
    networks:
      - servarr

  radarr:
    image: lscr.io/linuxserver/radarr:latest
    container_name: radarr
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ${APPDATA}/radarr:/config
      - ${DATA}:/data
    ports:
      - "7878:7878"
    restart: unless-stopped
    networks:
      - servarr

  sonarr:
    image: lscr.io/linuxserver/sonarr:latest
    container_name: sonarr
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ${APPDATA}/sonarr:/config
      - ${DATA}:/data
    ports:
      - "8989:8989"
    restart: unless-stopped
    networks:
      - servarr

  jellyfin:
    image: lscr.io/linuxserver/jellyfin:latest
    container_name: jellyfin
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ${APPDATA}/jellyfin:/config
      - ${DATA}/library:/data/library:ro
    ports:
      - "8096:8096"
    restart: unless-stopped
    networks:
      - servarr

  seerr:
    image: ghcr.io/seerr-team/seerr:latest
    container_name: seerr
    init: true
    environment:
      - TZ=${TZ}
      - LOG_LEVEL=info
      - PORT=5055
    volumes:
      - ${APPDATA}/seerr:/app/config
    ports:
      - "5055:5055"
    healthcheck:
      test: wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/settings/public || exit 1
      start_period: 20s
      timeout: 3s
      interval: 15s
      retries: 3
    restart: unless-stopped
    networks:
      - servarr

networks:
  servarr:
    name: servarr

Après le démarrage :

Interfaces :

Application Adresse
qBittorrent http://IP_DU_SERVEUR:8080
Prowlarr http://IP_DU_SERVEUR:9696
Radarr http://IP_DU_SERVEUR:7878
Sonarr http://IP_DU_SERVEUR:8989
Jellyfin http://IP_DU_SERVEUR:8096
Seerr http://IP_DU_SERVEUR:5055

Variante : Plex à la place de Jellyfin

Si vous utilisez Plex, remplacez simplement le service jellyfin par celui-ci. Le mode réseau host est couramment utilisé pour faciliter la découverte locale des lecteurs.

  plex:
    image: lscr.io/linuxserver/plex:latest
    container_name: plex
    network_mode: host
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
      - VERSION=docker
    volumes:
      - ${APPDATA}/plex:/config
      - ${DATA}/library:/data/library:ro
    restart: unless-stopped

Exemple 2 : qBittorrent avec VPN intégré et kill switch

Cet exemple remplace uniquement le service qbittorrent du premier compose. L’image binhex/arch-qbittorrentvpn inclut qBittorrent, WireGuard/OpenVPN et des règles réseau empêchant les fuites si le tunnel VPN tombe. Pour débuter, privilégiez Private Internet Access (PIA) ou AirVPN, qui sont plus simples à utiliser avec un port entrant stable dans ce type de conteneur. ProtonVPN est bien accepté par l’image via VPN_PROV=protonvpn, mais son port forwarding manuel repose sur NAT-PMP et demande un renouvellement régulier.

  qbittorrent:
    image: binhex/arch-qbittorrentvpn:latest
    container_name: qbittorrent
    privileged: true
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - UMASK=002
      - VPN_ENABLED=yes
      - VPN_USER=${VPN_USER}
      - VPN_PASS=${VPN_PASS}
      - VPN_PROV=pia
      - VPN_CLIENT=wireguard
      - STRICT_PORT_FORWARD=yes
      - LAN_NETWORK=${LAN_NETWORK}
      - NAME_SERVERS=1.1.1.1,1.0.0.1
      - ENABLE_PRIVOXY=no
      - WEBUI_PORT=8080
      - DEBUG=false
    volumes:
      - ${APPDATA}/qbittorrentvpn:/config
      - ${DATA}:/data
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "8080:8080"
    restart: unless-stopped
    networks:
      - servarr

privileged: true et net.ipv4.conf.all.src_valid_mark=1 sont nécessaires avec WireGuard selon la documentation de l’image. Les ports 8118 (Privoxy) et 9118 (SOCKS) ne sont pas ouverts ici car ces fonctions restent désactivées. Ne remplacez pas PUID, PGID par 0 : utilisez l’utilisateur propriétaire de vos dossiers.

Cas ProtonVPN

ProtonVPN peut fonctionner comme tunnel VPN dans binhex, mais son port forwarding n’est pas le plus simple pour cet usage.

D’après la documentation Proton, le port forwarding manuel utilise NAT-PMP. Le mapping est demandé pour 60 secondes et doit être renouvelé en boucle, par exemple toutes les 45 secondes, sinon le port expire.

En clair : ProtonVPN reste utilisable pour protéger le trafic torrent, mais je ne le recommande pas avec binhex/arch-qbittorrentvpn si votre objectif est un port entrant stable et simple à maintenir. Pour un débutant, PIA ou AirVPN sont plus adaptés avec cette image. Si vous tenez à utiliser ProtonVPN avec port forwarding, regardez plutôt du côté de Gluetun, qui documente ProtonVPN avec VPN_PORT_FORWARDING=on.

À vérifier après démarrage :

Exemple 3 : Applications optionnelles

Ce bloc peut être ajouté au compose de base quand le serveur fonctionne déjà. Il installe Profilarr, Maintainerr, Cleanuparr et Cross-seed ; leur configuration fonctionnelle est expliquée dans Optimiser les nouvelles applications.

  profilarr:
    image: santiagosayshey/profilarr:latest
    container_name: profilarr
    environment:
      - TZ=${TZ}
    volumes:
      - ${APPDATA}/profilarr:/config
    ports:
      - "6868:6868"
    restart: unless-stopped
    networks:
      - servarr

  maintainerr:
    image: ghcr.io/maintainerr/maintainerr:latest
    container_name: maintainerr
    user: "${PUID}:${PGID}"
    environment:
      - TZ=${TZ}
    volumes:
      - ${APPDATA}/maintainerr:/opt/data
    ports:
      - "6246:6246"
    restart: unless-stopped
    networks:
      - servarr

  cleanuparr:
    image: ghcr.io/cleanuparr/cleanuparr:latest
    container_name: cleanuparr
    environment:
      - TZ=${TZ}
      - PORT=11011
      - BASE_PATH=
      - PUID=${PUID}
      - PGID=${PGID}
      - UMASK=022
    volumes:
      - ${APPDATA}/cleanuparr:/config
      - ${DATA}:/data
    ports:
      - "11011:11011"
    restart: unless-stopped
    networks:
      - servarr

  cross-seed:
    image: ghcr.io/cross-seed/cross-seed:6
    container_name: cross-seed
    user: "${PUID}:${PGID}"
    volumes:
      - ${APPDATA}/cross-seed:/config
      - ${DATA}:/data
    ports:
      - "2468:2468"
    command: daemon
    restart: unless-stopped
    networks:
      - servarr

À retenir :

Vérifier avant de lancer

Avant un docker compose up -d, contrôlez :

Sources des modèles