Skip to main content

Installation Wolf (Multi-User Cloud Gaming)

Objectif : Faire tourner plusieurs instances de Steam indépendantes sur un ou plusieurs GPU, accessibles via Moonlight avec support manettes.manettes, en utilisant Wolf et la méthode Nvidia (Manual) sur Unraid.


1. Prérequis Système (Unraid)

A. Plugin Nvidia

Installer le plugin "Nvidia Driver" (par ich777) depuis les Community Applications.

Vérifier ensuite que les devices Nvidia existent bien :

ls -l /dev/nvidia* /dev/nvidia-caps

Et que uinput / uhid sont présents :

ls -l /dev/uinput /dev/uhid

B. Correctifs NVENC et NvFBC pour les pilotes Nvidia

Nvidia va bloquerbloque le nombre de streamflux NVENC au-delà de 3. Pour palierlever àcette celimite, blocage,on il faut appliquerapplique un patch.patch au chargement du driver.

Installer le plugin "User Scripts" depuis les Community Applications.
Créez

Créer ensuite un scriptscript, par exemple nommé "Nvidia NVENC Patch" avec comme contenu :

#!/bin/bash
wget https://raw.githubusercontent.com/keylase/nvidia-patch/master/patch.sh -O /tmp/nvidia-patch.sh
chmod +x ./tmp/nvidia-patch.sh
./tmp/nvidia-patch.sh

À lancer maintenant.une première fois manuellement.
RéglezDans unUser CRONScripts, régler le script pour qu’il s’exécute à chaque démarrage de l'Array.l’Array.

C. Activation du "Kernel Mode Setting" (⚠️)KMS)

Wolf a besoin de contrôler l'l’affichage au niveau du noyau pour créer les sessions graphiques. Sans ça, on risque l’écran noir.

  1. Aller dans Main > Flash > Syslinux Configuration.
  2. AjouterDans à la toute fin de votre configurationl’entrée Unraid OS, ajouter à la fin de la ligne :
    nvidia-drm.modeset=1
    

  3. Redémarrer Unraid.
  4. Vérifier que le KMS est bien activé :
    cat /sys/module/nvidia_drm/parameters/modeset
    # Doit renvoyer : Y
    

C.D. Persistance des Manettes.Manettes (uinput / uhid)

Pour que Unraid recrée correctement les règles de manettes virtuelles à chaque démarrage (sinon elles disparaissent auaprès reboot).

  1. Ouvrir le terminal Unraid.
  2. Éditer le fichier de boot : nano /boot/config/go
  3. Ajouter ce bloc à la fin du fichier :
# --- Wolf : Support Manettes Virtuelles ---
# 1. Permissions uinput
chmod 666 /dev/uinput || true

# 2. Règles UDEV
cat << 'EOF' > /etc/udev/rules.d/85-wolf-virtual-inputs.rules
KERNEL=="uinput", SUBSYSTEM=="misc", MODE="0660", GROUP="input", OPTIONS+="static_node=uinput"
KERNEL=="uhid", TAG+="uaccess"
SUBSYSTEMS=="input", ATTRS{id/vendor}=="ab00", MODE="0660", GROUP="input", ENV{ID_SEAT}="seat9"
SUBSYSTEMS=="input", ATTRS{name}=="Wolf X-Box One (virtual) pad", MODE="0660", GROUP="input"
SUBSYSTEMS=="input", ATTRS{name}=="Wolf PS5 (virtual) pad", MODE="0660", GROUP="input"
SUBSYSTEMS=="input", ATTRS{name}=="Wolf gamepad (virtual) motion sensors", MODE="0660", GROUP="input"
SUBSYSTEMS=="input", ATTRS{name}=="Wolf Nintendo (virtual) pad", MODE="0660", GROUP="input"
EOF

# 3. Recharger les règles
udevadm control --reload-rules && udevadm trigger

2. Installation de Wolf (DockerMéthode Compose)Nvidia Manual sur Unraid)

UtiliserAvec la méthode Nvidia Manual, on va :

    Construire une image Docker qui contient les fichiers du driver Nvidia. Pré-remplir un volume Docker nvidia-driver-vol avec ces fichiers. Monter ce volume dans le conteneur Wolf via un template Unraid.

    A. Construire l’image gow/nvidia-driver:latest

    Dans le terminal Unraid :

    cd /root
    
    curl https://raw.githubusercontent.com/games-on-whales/gow/master/images/nvidia-driver/Dockerfile \
      | docker build -t gow/nvidia-driver:latest -f - --build-arg NV_VERSION=$(cat /sys/module/nvidia/version) .
    

    Cela crée l’image locale gow/nvidia-driver:latest avec la version de driver actuellement chargée.

    B. Créer / mettre à jour le volume Docker nvidia-driver-vol

    On pré-popule un volume Docker avec les libs Nvidia :

    docker create --rm \
      --mount source=nvidia-driver-vol,destination=/usr/nvidia \
      gow/nvidia-driver:latest sh
    

    Vérifier qu’il existe :

    docker volume ls | grep nvidia-driver
    # Doit afficher : nvidia-driver-vol
    

    C. Script User Scripts : reconstruire le volume après chaque reboot

    Important : à chaque mise à jour du driver Nvidia, il faut reconstruire l’image et repopuler le volume, sinon Wolf utilise des libs qui ne correspondent plus au driver chargé.

    Le plus simple sur Unraid : utiliser le plugin DockerUser ComposeScripts Manageravec un script lancé au démarrage de l’Array.

      Dans User Scripts, créer un script nommé par exemple "Wolf - Rebuild Nvidia driver volume". CréerContenu du script :
      #!/bin/bash
      # Wolf - (Re)construction de l'image et du volume driver Nvidia
      
      # 1. Rebuild de l'image gow/nvidia-driver:latest avec la version de driver actuellement chargée
      curl -s https://raw.githubusercontent.com/games-on-whales/gow/master/images/nvidia-driver/Dockerfile \
        | docker build -t gow/nvidia-driver:latest -f - --build-arg NV_VERSION=$(cat /sys/module/nvidia/version) .
      
      # 2. (Re)population du volume nvidia-driver-vol
      docker create --rm \
        --mount source=nvidia-driver-vol,destination=/usr/nvidia \
        gow/nvidia-driver:latest sh
      
        Configurer le script pour s’exécuter à chaque démarrage de l’Array.

        À chaque reboot (après une stackmaj nomméede wolf.

        Puisdriver éditerpar exemple), le Stackvolume etsera cliquezautomatiquement synchronisé avec la bonne version.

        D. Création automatique du template Unraid Composemy-wolf.xml

        File

        On va créer directement le template Unraid via une commande dans le terminal, pour qu’il apparaisse dans Docker > Add Container.

        Fichier

        docker-compose.ymlDans le terminal Unraid, lancer :
        services:mkdir wolf:-p image:/boot/config/plugins/dockerMan/templates-user
        
        cat << 'EOF' > /boot/config/plugins/dockerMan/templates-user/my-wolf.xml
        
        
            wolf
            ghcr.io/games-on-whales/wolf:stable
            container_name: wolf
            restart: unless-stopped
            # Le modehttps://ghcr.io/
            host
            
            bash
            false
            https://games-on-whales.github.io/wolf/stable/
            https://github.com/games-on-whales/wolf
            Wolf est impératifun serveur de streaming Moonlight permettant de partager un hôte pour plusieurs sessions de jeu et bureaux virtuels.
            GameServers:
            
            
            https://games-on-whales.github.io/assets/favicon.png
            -v nvidia-driver-vol:/usr/nvidia:rw --device-cgroup-rule="c 13:* rmw"
            
            
            0
            
            
            Wolf est un serveur de streaming Moonlight (découvertepermettant réseau)de network_mode:partager un hôte pour plusieurs sessions de jeu et bureaux virtuels.
        
            
                host
                
            
        
            
                
                    privileged:/mnt/user/appdata/wolf
                    true/etc/wolf
                    environment:
              - PUID=1000
              - PGID=1000
              - NVIDIA_DRIVER_CAPABILITIES=all
              - NVIDIA_VISIBLE_DEVICES=all
              - WOLF_LOG_LEVEL=INFO
              
            volumes:
              # CRITIQUE : Permet à Wolf de piloter le Docker d'Unraid pour lancer les jeux
              -rw
                
                
                    /var/run/docker.sock:sock
                    /var/run/docker.sock:sock
                    rw
                
                
                    #/dev
                    Configuration/dev
                    etrw
                
                
                    données/run/udev
                    persistantes/run/udev
                    -rw
                
            
        
            
                
                    nvidia-driver-vol
                    NVIDIA_DRIVER_VOLUME_NAME
                    
                
            
        
            
        
            
        
            /mnt/user/appdata/wolf/config:/etc/wolf
        
            -/var/run/docker.sock
        
            /mnt/user/appdata/wolf/data:dev
        
            /var/lib/wolfrun/udev
        
            #nvidia-driver-vol
        
            Dossier/dev/dri
        
            /dev/nvidiactl
        
            Xorg/dev/nvidia0
        
            /dev/nvidia-modeset
        
            /dev/nvidia-uvm
        
            /dev/nvidia-uvm-tools
        
            /dev/nvidia-caps/nvidia-cap1
        
            /dev/nvidia-caps/nvidia-cap2
        
            /dev/uinput
        
            /dev/uhid
        
        
        EOF
        
          Aller dans Docker > Add Container et Waylandchoisir stockentle leurstemplate socketswolf (utile pourdans la communicationliste inter-processus)déroulante. -Normalement, /tmp/.X11-unix:/tmp/.X11-unix:rwtout #est Indispensabledéjà correctement renseigné. Cliquer sur Apply pour créer deset périphériquesdémarrer -le /dev/:/dev/:rwconteneur #Wolf. Indispensable pour
          que

          3. Linux détecte l'insertionConfiguration de laWolf manette(config.toml -& /run/udev:/run/udev:rwutilisateurs)

          # Configuration spécifique pour le plugin Nvidia d'Unraid runtime: nvidia device_cgroup_rules: - 'c 13:* rmw'

          Enregistrez et cliquez update stack puis compose up


          A. Modifier le config.toml


          Fichier cible (côté host) :

          nano /mnt/user/appdata/wolf/config/cfg/config.toml
          

          À titre perso, pour le moment, j'j’ai choisi d’épuréépurer totalement l'l’affichage dans Moonlight.
           Mais il est possible de laisser l'l’app Wolf UI présente.présente,
          Ellequi permet de classer les appapps par utilisateur.
          Ça peut être pratique, mais là je vous montre simplement au plus simple pour ajouter Steam.


          Dans ce fichier, vous supprimez toustout ce qu'qu’il y a entre :

          [[profiles]]
          id = 'moonlight-profile-id'
          

          et 

          [[profiles]]
          id = 'user'
          name = 'User'
          

          Et vous collez à la place,place la configuration de votre premier utilisateur suivante :

          RemplacerRemplacez bien les quatre <NOM_DU_COMPTE>.
          RemplacerRemplacez <url-image-png> par une image PNG. Dimension idéale width=112px height=150px (facilement Ça permettra à votre utilisateur de reconnaitre son comptereconnaissable dans Moonlight.Moonlight).

          # --- Utilisateur 1 : <NOM_DU_COMPTE> ---
              [[profiles.apps]]
              icon_png_path = '<url-image-png>'
              start_virtual_compositor = true
              title = '<NOM_DU_COMPTE>'
          
                  [profiles.apps.runner]
                  base_create_json = '''{
            "HostConfig": {
              "IpcMode": "host",
              "CapAdd": ["SYS_ADMIN", "SYS_NICE", "SYS_PTRACE", "NET_RAW", "MKNOD", "NET_ADMIN"],
              "SecurityOpt": ["seccomp=unconfined", "apparmor=unconfined"],
              "Ulimits": [{"Name":"nofile", "Hard":10240, "Soft":10240}],
              "Privileged": false,
              "DeviceCgroupRules": ["c 13:* rmw", "c 244:* rmw"]
            }
          }
          '''
                  devices = []
                  env = [
                      'PROTON_LOG=1',
                      'RUN_SWAY=true',
                      'GOW_REQUIRED_DEVICES=/dev/input/* /dev/dri/* /dev/nvidia*',
                      'XKB_DEFAULT_LAYOUT=fr',
                      'TZ=Europe/Paris'
                  ]
                  image = 'ghcr.io/games-on-whales/steam:edge'
                  mounts = [
                      '/mnt/user/Games:/home/retro/games-unraid:rw',
                      '/mnt/user/appdata/wolf/<NOM_DU_COMPTE>:/home/retro/.steam:rw'
                  ]
                  name = '<NOM_DU_COMPTE>'
                  ports = []
                  type = 'docker'
          

          'XKB_DEFAULT_LAYOUT=fr'Permet d'avoir le clavier françaisAZERTY en AZERTYfrançais.
          'TZ=Europe/Paris'Sinon l'horaire ne sera pasheure correcte dans l'app
          l’app.

          '/mnt/user/Games:/home/retro/games-unraid:rw',Pointpoint de montage du répertoire d'd’installation des jeuxjeux.
          '/mnt/user/appdata/wolf/<NOM_DU_COMPTE>:/home/retro/.steam:rw'Permetrend de rendre persistant l'l’installation de Steam. Sinon un nouveau Steam estpersistante installé pour chaque Moonlight du mêmepar utilisateur.

          B. Préparation des dossiers (Permissions)

          Après avoir ajouté un utilisateur dans le fichier TOML, nouson allons créercrée son dossier spécifique et fixeron fixe les droits :droits.

          Création d'd’un répertoire utilisateur :

          mkdir -p /mnt/user/appdata/wolf/<NOM_DU_COMPTE>
          

          Application des droits (Utilisateur 1000) :

          chown -R 1000:1000 /mnt/user/appdata/wolf
          chmod -R 777 /mnt/user/appdata/wolf
          

          Droits sur le dossier des jeux :

          chown -R 1000:1000 /mnt/cache/Games
          chmod -R 777 /mnt/cache/Games
          

          Pensez bien à faire ça à chaque nouvel ajout d'd’un utilisateur dans le fichier TOML. Sinon votre Moonlight se fermera à chaque lancement du Steam concerné, à cause d'd’un manque de droits.

          Faire ce changement de droit après la création du compte et le reboot du Docker wolf.Wolf.

          3b. Variante des gestions d'utilisateurs.d’utilisateurs

          Wolf UI

          Wolf UI permet d'd’avoir un répertoire par utilisateur.
          Il y a deux principaux avantages à l'utiliser :

          • Pouvoir rangersRanger toutes les appapps par dossiers utilisateurs.utilisateur.
          •  Lorsque vous avez besoin d'utiliserUtiliser le mode co-op. Afin que (deux utilisateurs puissent se connecter sur la même session pour jouer en coop locale.locale).

          Activation de Wolf UI

          Faire apparaitreapparaître le menu Wolf UI dans moonlight.Moonlight

          Pour activer wolfWolf UI, il faut modifier config.toml,toml, repérezrepérer la partie :

          [[profiles]]
          id = 'moonlight-profile-id'
          

          Directement dessous, collez :

          [[profiles.apps]]
              icon_png_path = 'https://raw.githubusercontent.com/games-on-whales/wolf-ui/refs/heads/main/src/Icons/wolf_ui_icon.png'
              start_virtual_compositor = true
              title = 'Wolf UI'
          
                  [profiles.apps.runner]
                  base_create_json = '''{
                "HostConfig": {
                  "IpcMode": "host",
                  "CapAdd": ["NET_RAW", "MKNOD", "NET_ADMIN", "SYS_ADMIN", "SYS_NICE"],
                  "Privileged": false,
                  "DeviceCgroupRules": ["c 13:* rmw", "c 244:* rmw"]
                }
              }'''
                  devices = []
                  env = [
                      'GOW_REQUIRED_DEVICES=/dev/input/event* /dev/dri/* /dev/nvidia*',
                      'WOLF_SOCKET_PATH=/var/run/wolf/wolf.sock',
                      'WOLF_UI_AUTOUPDATE=False',
                      'LOGLEVEL=INFO',
                      'XKB_DEFAULT_LAYOUT=fr'
                  ]
                  image = 'ghcr.io/games-on-whales/wolf-ui:main'
                  mounts = [ '/var/run/wolf/wolf.sock:/var/run/wolf/wolf.sock' ]
                  name = 'Wolf-UI'
                  ports = []
                  type = 'docker'
          
          Création des espaces utilisateur.utilisateur

          De base, dans le fichier config.toml,toml, un utilisateur user est créé avec toutes les app activéesapps dedans.

          Vous pouvez créer un nouvel espace en rajoutant ceciajoutant :

          [[profiles]]
          id = 'user'user1'
          name = 'NOM_UTILISATEUR'
          

          Pensez à différentierdifférencier les id 'user1': 'user2'user1, user2, etc...

          toutesToutes les appapps de cet utilisateur doivent êtresêtre présentes sous ces lignes.


          4. Configuration Post-Installation

          A. Appairage Moonlight

          1. Lancer Moonlight sur le client (PC, TV, Tablette).
          2. Noter le code PIN affiché.
          3. Consulter les logs Docker : docker logs -f wolf
          4. Cliquer sur le lien http://IP_UNRAID:47989/pin/ID visible dans les logs et entrezentrer le code pinPIN aà 4 chiffrechiffres demandéaffiché par l'instancedans Moonlight.


            image.png

          5. Ça vous ouvre uneLa page web quivous demande de renseigner le PIN pour déverrouiller Moonlight.


            image.png

          À la première ouverture de Steam, ça installe le dépôt,dépôt s’installe, puis il faut vous connecter à votre compte avec le Steam Guard.

          B. Déclaration des Jeuxjeux dans Steam

          Par défaut, Steam n'ane connaît pas le disque d'd’installation des jeux que nous avons configurésconfiguré dans le fichier config.toml. Si vous laissez tel quel, il va installer les jeux dans votrele répertoire appdata, et(non departagé faitentre ne sera pas commun à tous les utilisateurs.utilisateurs).

          1. FermezFermer Big Picture.
          2. Dans Steam, allezaller dans Paramètres > Stockage.
          3. Ajouter un lecteur > Remonterremonter à  /Home > Sélectionnersélectionner le dossier /games-unraid.
          4. Le définir comme lecteur par défaut (étoile).

          Il faudraÀ faire ça pour chaque compte Steam.

          C. MangoHud

          L’overlay Steam ne fonctionne actuellement pas dans le conteneur Wolf. Donc pourPour voir les FPS et d’autres statistiques,stats, ilon faut utiliserutilise MangoHud.MangoHud.

          Il est déjà installé et activé dans l’image Steam par défaut pour tous les jeux Vulkan (y compris les jeux Proton).

          mangohud_example.gif

          MangoHud

          Jeux OpenGL (Linux natif)

          Bien que mangohud soit déjà installé, il n'est pas possible de l'activer globalement pour tousPour les jeux OpenGL.OpenGL, Vousvous pouvez toutefois l'l’activer jeu par jeu en ajoutant la commande :

          mangohud %command%
          

          image.png

          Activation et configuration

          En jeu, vous pouvez appuyer sur Maj droite + F12 pour faireafficher/masquer apparaître et disparaître l'interface. MangoHud.
          Vous pouvez également appuyerEt sur Maj droite + F11 pour modifierchanger sa position à l'l’écran.


          5. Accès à Distance (Ouverture de Ports)

          Wolf ne gère pas l'l’UPnP. Pour jouer depuis l'l’extérieur, vous avez deux options :

          Option A : VPN (Recommandé)

          UtilisezUtiliser Tailscale ou Wireguard (Pluginsplugins Unraid). C'C’est plus sécurisé et ne nécessite aucune ouverture de port.
           (Plus chiant côté FireTV ou autreautre, :mais c’est la vie 😄)

          Option B : Ouverture de Ports (NAT)

          Si vous n'utilisez pas deSans VPN, redirigezrediriger les ports suivants sur votre routeur vers l'l’IP de votredu serveur Unraid :

            TCP 47984 : HTTPS (Sécurité)sécurité) TCP 47989 : HTTP (Appairageappairage Web) TCP 48010 : RTSP (Initialisationinitialisation du stream) UDP 47999 : Contrôle (Manettes)manettes) UDP 48100 : Flux Vidéovidéo (RTP - Spécifiquespécifique Wolf) UDP 48200 : Flux Audioaudio (RTP - Spécifiquespécifique Wolf)