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, 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 bloque le nombre de flux NVENC au-delà de 3. Pour lever cette limite, on applique un patch au chargement du driver.

Installer le plugin "User Scripts" depuis les Community Applications.


Créer ensuite un script, 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 une première fois manuellement.
Dans User Scripts, régler le script pour qu’il s’exécute à chaque démarrage de l’Array.

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

Wolf a besoin de contrôler 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. Dans l’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
    #

    Il Doitdoit renvoyer : Y

D. Persistance des Manettes (uinput / uhid)

Pour que Unraid recrée correctement les règles de manettes virtuelles à chaque démarrage (sinon elles disparaissent aprè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 (Méthode Nvidia Manual sur Unraid)

Avec 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 User Scripts avec un script lancé au démarrage de l’Array.

  1. Dans User Scripts, créer un script nommé par exemple "Wolf - Rebuild Nvidia driver volume".
  2. Contenu 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
  1. Configurer le script pour s’exécuter à chaque démarrage de l’Array.

À chaque reboot (après une maj de driver par exemple), le volume sera automatiquement synchronisé avec la bonne version.

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

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

  1. Dans le terminal Unraid, lancer :
mkdir -p /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
    https://ghcr.io/
    host
    
    bash
    false
    https://games-on-whales.github.io/wolf/stable/
    https://github.com/games-on-whales/wolf
    Wolf est un 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 permettant de partager un hôte pour plusieurs sessions de jeu et bureaux virtuels.

    
        host
        
    

    
        
            /mnt/user/appdata/wolf
            /etc/wolf
            rw
        
        
            /var/run/docker.sock
            /var/run/docker.sock
            rw
        
        
            /dev
            /dev
            rw
        
        
            /run/udev
            /run/udev
            rw
        
    

    
        
            nvidia-driver-vol
            NVIDIA_DRIVER_VOLUME_NAME
            
        
    

    

    

    /mnt/user/appdata/wolf

    /var/run/docker.sock

    /dev

    /run/udev

    nvidia-driver-vol

    /dev/dri

    /dev/nvidiactl

    /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
  1. Aller dans Docker > Add Container et choisir le template wolf dans la liste déroulante. Normalement, tout est déjà correctement renseigné.
  2. Cliquer sur Apply pour créer et démarrer le conteneur Wolf.

3. Configuration de Wolf (config.toml & utilisateurs)

A. Modifier le config.toml

Fichier cible (côté host) :

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

À titre perso, pour le moment, j’ai choisi d’épurer totalement l’affichage dans Moonlight. Mais il est possible de laisser l’app Wolf UI présente, qui permet de classer les apps par utilisateur.

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

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

et 

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

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

Remplacez bien les quatre <NOM_DU_COMPTE>.
Remplacez <url-image-png> par une image PNG. Dimension idéale width=112px height=150px (facilement reconnaissable dans 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' → clavier AZERTY français.
'TZ=Europe/Paris' → heure correcte dans l’app.

'/mnt/user/Games:/home/retro/games-unraid:rw' → point de montage du répertoire d’installation des jeux.
'/mnt/user/appdata/wolf/<NOM_DU_COMPTE>:/home/retro/.steam:rw' → rend l’installation de Steam persistante par utilisateur.

B. Préparation des dossiers (Permissions)

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

Création 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’un utilisateur dans le fichier TOML. Sinon Moonlight se fermera à chaque lancement du Steam concerné, à cause d’un manque de droits.

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

3b. Variante des gestions d’utilisateurs

Wolf UI

Wolf UI permet d’avoir un répertoire par utilisateur.

  • Ranger toutes les apps par utilisateur.
  • Utiliser le mode co-op (deux utilisateurs sur la même session en coop locale).

Activation de Wolf UI

Faire apparaître le menu Wolf UI dans Moonlight

Pour activer Wolf UI, il faut modifier config.toml, repé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

De base, dans config.toml, un utilisateur user est créé avec toutes les apps dedans.

Vous pouvez créer un nouvel espace en ajoutant :

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

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

Toutes les apps de cet utilisateur doivent ê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 entrer le code PIN à 4 chiffres affiché dans Moonlight.
    image.png
  5. La page web vous demande de renseigner le PIN pour déverrouiller Moonlight.
    image.png

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

B. Déclaration des jeux dans Steam

Par défaut, Steam ne connaît pas le disque d’installation des jeux configuré dans config.toml. Si vous laissez tel quel, il va installer les jeux dans le répertoire appdata (non partagé entre utilisateurs).

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

À faire pour chaque compte Steam.

C. MangoHud

L’overlay Steam ne fonctionne pas dans le conteneur Wolf. Pour voir les FPS et autres stats, on utilise MangoHud.

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

MangoHud

Jeux OpenGL (Linux natif)

Pour les jeux OpenGL, vous pouvez l’activer jeu par jeu en ajoutant :

mangohud %command%

image.png

Activation et configuration

En jeu, vous pouvez appuyer sur Maj droite + F12 pour afficher/masquer MangoHud.
Et sur Maj droite + F11 pour changer sa position à l’écran.


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

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

Option A : VPN (Recommandé)

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

Option B : Ouverture de Ports (NAT)

Sans VPN, rediriger les ports suivants sur votre routeur vers l’IP du serveur Unraid :

  • TCP 47984 : HTTPS (sécurité)
  • TCP 47989 : HTTP (appairage Web)
  • TCP 48010 : RTSP (initialisation du stream)
  • UDP 47999 : Contrôle (manettes)
  • UDP 48100 : Flux vidéo (RTP - spécifique Wolf)
  • UDP 48200 : Flux audio (RTP - spécifique Wolf)