
Introduction #
À l’heure où les services de streaming se multiplient et fragmentent vos bibliothèques multimédia, reprendre le contrôle de vos contenus numériques devient un enjeu majeur. Entre les abonnements coûteux, les restrictions géographiques et la dépendance aux plateformes, l’auto-hébergement d’un serveur multimédia offre une alternative séduisante : liberté totale, confidentialité garantie et coûts maîtrisés.
Dans cet article, nous allons apprendre à déployer une stack mediaserver complète et moderne qui combine streaming vidéo, streaming musical, gestion d’ebooks et analytics d’écoute. Nous allons couvrir l’installation de Jellyfin (serveur de streaming vidéo avec transcodage matériel iGPU Intel), Tiny Media Manager (gestion des métadonnées vidéo), Jellystat (statistiques et analytics Jellyfin), Navidrome (serveur de streaming musical compatible Subsonic), BookLore (gestion d’ebooks), Maloja (analytics d’écoute type Last.fm), Multi-Scrobbler (synchronisation des écoutes) et Music Assistant (contrôle multi-room et intégration Home Assistant).
Ce tutoriel suppose que vous avez déjà des connaissances en Docker et Docker Compose, un serveur Linux fonctionnel (VM ou conteneur LXC sous Proxmox par exemple), et une bibliothèque multimédia organisée (vidéos, musique et/ou livres).
L’architecture proposée s’intègre parfaitement dans un environnement homelab tel que présenté dans les articles précédents de cette série.
Table des matières #
- 🖥️ Préparation du conteneur LXC Proxmox
- 🔭 Vue d’ensemble de l’architecture
- 📋 Prérequis techniques
- 📁 Structure du projet
- ⚙️ Configuration des services
- 🚀 Déploiement étape par étape
- ✅ Vérification et tests
- 🔧 Maintenance et monitoring
- 🔍 Troubleshooting
- ⚡ Optimisations et bonnes pratiques
- 🎯 Conclusion
🖥️ Préparation du conteneur LXC Proxmox #
Création du conteneur LXC en ligne de commande #
Téléchargement du template Debian 13 #
Connectez-vous à votre serveur Proxmox via SSH et téléchargez le template Debian 13 :
# Télécharge le template Debian 13 dans le stockage local
pveam update
pveam download local debian-13-standard_13.0-1_amd64.tar.zst
Création du conteneur #
Créez le conteneur LXC avec la commande pct create :
pct create 140 iso-morpheus:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst \
--hostname mediaserver \
--memory 8086 \
--cores 4 \
--rootfs datastore-zfs:64 \
--net0 name=eth0,bridge=vmbr0,firewall=1,gw=10.10.20.1,ip=10.10.20.40/24,tag=20,type=veth \
--nameserver 192.168.0.53 \
--searchdomain home.allfabox.fr \
--password \
--unprivileged 0 \
--features nesting=1,keyctl=1 \
--onboot 1 \
--startup order=4
Explication des paramètres :
| Paramètre | Valeur | Description |
|---|---|---|
| ID | 140 | Identifiant unique du conteneur dans Proxmox |
--hostname |
frontend | Nom d’hôte du conteneur |
--memory |
8086 | RAM allouée en MB (≈8 Go - dimensionnement pour Music Assistant + base de données) |
--cores |
2 | Nombre de cœurs CPU dédiés |
--rootfs |
datastore-zfs:32 | Disque système de 32 GB sur le stockage ZFS datastore-zfs |
--net0 |
… | Configuration réseau détaillée ci-dessous |
--searchdomain |
home.allfabox.fr | Domaine de recherche DNS local |
--unprivileged |
0 | Conteneur privilégié (voir avertissement de sécurité) |
--features |
nesting=1,keyctl=1 | Nécessaire pour Docker dans LXC |
--onboot |
1 | Démarre automatiquement au boot de Proxmox |
--startup |
order=4 | Ordre de démarrage (après les services réseau) |
Détail de la configuration réseau (--net0) :
| Paramètre | Valeur | Description |
|---|---|---|
name |
eth0 | Nom de l’interface réseau |
bridge |
vmbr0 | Bridge réseau Proxmox |
firewall |
1 | Firewall activé |
gw |
10.10.20.1 | Passerelle par défaut |
ip |
10.10.20.40/24 | Adresse IP statique avec masque /24 |
tag |
20 | VLAN 20 (réseau Proxmox) |
type |
veth | Type d’interface réseau virtuelle |
nesting=1 et keyctl=1 sont indispensables pour exécuter Docker dans un conteneur LXC. Sans ces options, Docker ne démarrera pas correctement.
Avertissement de sécurité : Conteneur LXC privilégié
Le paramètre --unprivileged 0 crée un conteneur privilégié, ce qui signifie que :
Risques de sécurité importants :
- L’utilisateur root dans le conteneur correspond à l’utilisateur root de l’hôte Proxmox
- Une compromission du conteneur peut entraîner une compromission complète de l’hôte Proxmox
- Les processus du conteneur ont un accès quasi-illimité aux ressources système de l’hôte
- En cas de faille de sécurité (CVE Docker, vulnérabilité applicative), un attaquant pourrait s’échapper du conteneur LXC
Pourquoi utiliser un conteneur privilégié ici ?
Dans certains cas, Docker dans un conteneur LXC non-privilégié peut rencontrer des problèmes de :
- Mapping des UID/GID complexe
- Permissions sur les volumes montés
- Compatibilité avec certaines images Docker (notamment Music Assistant en mode host)
Recommandations de sécurité :
- Isolation réseau : Ce conteneur est placé dans le VLAN 20 (réseau Proxmox), séparé du réseau de confiance
- Pare-feu strict : N’autorisez que les ports nécessaires (4533, 6060, 42010, etc.)
- Mises à jour régulières : Appliquez systématiquement les mises à jour de sécurité (Debian, Docker, images)
- Monitoring actif : Surveillez les logs système et les comportements anormaux
- Snapshots réguliers : Effectuez des sauvegardes fréquentes avec
vzdumpavant toute modification - Limitez l’accès SSH : Restreignez l’accès root au conteneur et utilisez des clés SSH plutôt que des mots de passe
- Principe du moindre privilège : N’exposez que les services strictement nécessaires
Alternative plus sécurisée :
Si votre environnement le permet, envisagez d’utiliser un conteneur non-privilégié (--unprivileged 1) avec un mapping d’UID/GID correct :
# Dans /etc/pve/lxc/140.conf (après création)
lxc.idmap: u 0 100000 1000
lxc.idmap: g 0 100000 1000
lxc.idmap: u 1000 1000 1
lxc.idmap: g 1000 1000 1
lxc.idmap: u 1001 101001 64535
lxc.idmap: g 1001 101001 64535
Cependant, cette configuration nécessite des ajustements supplémentaires pour Docker et peut compliquer le déploiement, notamment avec Music Assistant qui utilise network_mode: host.
Pour un environnement de production critique, privilégiez :
- Une VM complète (plutôt qu’un conteneur LXC) avec isolation matérielle renforcée
Configuration avancée du conteneur LXC #
Avant de démarrer le conteneur, configurons les points de montage et le transcodage matériel pour Jellyfin :
Ajout des points de montage (bind mounts) #
Caractéristique clé de l’architecture Perfect Homelab
Les bind mounts LXC permettent de monter directement des répertoires de l’hôte Proxmox dans le conteneur. Cette approche est fondamentale dans l’architecture Perfect Homelab car elle permet :
Avantages des bind mounts vs NFS/SMB :
- Performance native : Accès disque direct sans overhead réseau
- Latence minimale : Pas de stack TCP/IP à traverser
- Simplicité : Aucune configuration réseau ou firewall supplémentaire
- Fiabilité : Pas de dépendance à un service réseau qui pourrait tomber
- Permissions simplifiées : Mapping direct des UID/GID
Architecture MergerFS : Le pool /mnt/storage sur l’hôte Proxmox agrège plusieurs disques physiques en un système de fichiers unifié (voir Perfect Homelab E06). Les conteneurs LXC y accèdent directement comme s’il s’agissait d’un disque local.
Bind mounts depuis l’hôte Proxmox #
# Monte le stockage média principal (pool MergerFS)
pct set 140 -mp0 /mnt/storage/media,mp=/mnt/media
# Monte le dossier de sauvegardes Restic
pct set 140 -mp1 /mnt/fast2/backups/restic/docker/appdata,mp=/mnt/backups/restic
Explication des paramètres :
| Paramètre | Description |
|---|---|
-mp0 |
Numéro du mount point (0, 1, 2, etc.) |
/mnt/storage/media |
Chemin source sur l’hôte Proxmox (pool MergerFS) |
mp=/mnt/media |
Chemin destination dans le conteneur LXC |
Astuce : Les bind mounts sont configurés dans /etc/pve/lxc/140.conf et persistent aux redémarrages. Vous pouvez les visualiser avec :
cat /etc/pve/lxc/140.conf | grep mp0
Transcodage matériel (iGPU Intel) #
Pour permettre à Jellyfin d’utiliser le GPU Intel pour le transcodage matériel, nous devons passer les périphériques /dev/dri au conteneur :
# Vérification du GID du groupe render (doit être 104)
cat /etc/group | grep render
Sortie attendue : render:x:104:
group_add: - 104) pour autoriser l’accès au GPU. Si votre système utilise un GID différent, ajustez le fichier docker-compose.yml de Jellyfin en conséquence.
Ajoutez les périphériques GPU au fichier de configuration du conteneur LXC :
# Ajoute les périphériques de transcodage iGPU Intel
cat >> /etc/pve/lxc/140.conf << 'EOF'
lxc.cgroup2.devices.allow: c 226:0 rwm
lxc.cgroup2.devices.allow: c 226:128 rwm
lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file
lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
EOF
Explication des permissions :
| Périphérique | Description | Permissions |
|---|---|---|
c 226:0 |
/dev/dri/card0 - Contrôleur GPU principal |
rwm (read/write/mknod) |
c 226:128 |
/dev/dri/renderD128 - Interface de rendu GPU |
rwm (read/write/mknod) |
optional dans lxc.mount.entry empêche le conteneur de crasher si le périphérique GPU n’est pas disponible (utile pour les migrations ou tests).
Ajout des tags Proxmox #
Pour organiser vos conteneurs dans l’interface Proxmox, ajoutez des tags descriptifs :
# Ajoute les tags pour identification rapide
cat >> /etc/pve/lxc/140.conf << 'EOF'
tags: mediaserver;jellies;prod
EOF
Tags utilisés :
mediaserver: Indique que c’est un serveur multimédiajellies: Référence à Jellyfin (nom du projet)prod: Environnement de production
Démarrage du conteneur #
# Démarre le conteneur
pct start 140
# Vérifie le statut
pct status 140
# Entre dans le conteneur
pct enter 140
Sortie attendue :
starting container...
container started
Vérification du transcodage matériel #
Une fois dans le conteneur, vérifiez que les périphériques GPU sont bien montés :
# Vérifie la présence des périphériques DRI
ls -la /dev/dri/
# Vérifie que le groupe render est accessible
getent group render
Sortie attendue :
drwxr-xr-x 2 root root 100 Dec 5 10:00 .
drwxr-xr-x 5 root root 340 Dec 5 10:00 ..
crw-rw---- 1 root render 226, 0 Dec 5 10:00 card0
crw-rw---- 1 root render 226, 128 Dec 5 10:00 renderD128
card0 et renderD128 avec les bonnes permissions (groupe render), le transcodage matériel Jellyfin est prêt !
Configuration initiale du conteneur #
Une fois dans le conteneur, effectuez la configuration de base :
Mise à jour du système #
# Met à jour les dépôts et le système
apt update
apt upgrade -y
ping google.com.
Installation de Docker et Docker Compose #
# Installe les dépendances
apt install -y ca-certificates curl gnupg lsb-release
# Ajoute la clé GPG officielle de Docker
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
# Ajoute le dépôt Docker aux sources Apt
tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
apt update
# Installation des paquets Docker
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Vérifie l'installation
systemctl status docker
docker --version
docker compose version
Versions attendues :
Docker version 27.x.x
Docker Compose version 2.x.x
active (running) et que les versions s’affichent correctement, l’installation est réussie !
Création de l’utilisateur pour la stack #
Créez un utilisateur dédié (UID 1000) pour gérer la stack mediaserver :
# Crée l'utilisateur avec UID 1000
useradd -m -u 1000 -s /bin/bash mediaserver
# Définit un mot de passe
passwd mediaserver
# Ajoute l'utilisateur au groupe docker
usermod -aG docker mediaserver
# Ajoute l'utilisateur au groupe sudo (optionnel)
usermod -aG sudo mediaserver
Création de la structure de dossiers #
# Crée le répertoire de travail principal
mkdir -p /opt/docker/mediaserver-stack
# Donne les droits à l'utilisateur (UID 1000)
chown -R 1000:1000 /opt/docker
chmod -R 755 /opt/docker
/opt/docker/mediaserver-stack.
Vérification des montages de médias (bind mounts LXC) #
Architecture Perfect Homelab : Stockage unifié MergerFS
Dans l’architecture Perfect Homelab, les médias sont stockés sur un pool MergerFS unifié directement monté sur l’hôte Proxmox (voir Perfect Homelab E06 : Post-Installation [Données et stockage]).
Avantage clé : Les conteneurs LXC peuvent accéder directement à ce stockage via bind mounts (montages directs depuis l’hôte), éliminant :
- La latence réseau du NFS/SMB
- La complexité de configuration réseau
- Les problèmes de permissions
- Le overhead protocole
Les montages ont été configurés lors de la création du conteneur LXC :
pct set 140 -mp0 /mnt/storage/media,mp=/mnt/media
Cette approche offre des performances natives (accès disque direct) tout en conservant la flexibilité de MergerFS pour étendre le stockage.
Vérifiez que les montages bind sont actifs dans le conteneur :
# Vérifie les points de montage
df -h | grep media
# Vérifie l'accès aux médias
ls -lah /mnt/media/
ls -lah /mnt/media/musics/
ls -lah /mnt/media/books/
ls -lah /mnt/media/videos/
Sortie attendue :
/mnt/media 4.0T 2.1T 1.9T 53% /mnt/media
Rappel architecture : Le pool /mnt/storage sur l’hôte Proxmox agrège plusieurs disques physiques via MergerFS, offrant :
- Extensibilité : Ajoutez des disques à la volée sans réorganiser les données
- Flexibilité : Mélangez tailles et systèmes de fichiers (ext4, xfs)
- Simplicité : Vu comme un seul système de fichiers par les conteneurs LXC
- Performance : Accès direct sans couche réseau
Pour plus de détails sur la configuration MergerFS, consultez l’article Perfect Homelab E06.
Vérification finale de la configuration #
# Vérifie que Docker fonctionne avec l'utilisateur non-root
su - mediaserver
docker run --rm hello-world
Sortie attendue :
Hello from Docker!
This message shows that your installation appears to be working correctly.
🔭 Vue d’ensemble de l’architecture #
Schéma de l’architecture #
graph TB
subgraph streaming[Streaming Musical]
NAV["Navidrome
Serveur Subsonic"]
MA["Music Assistant
Multi-room"]
MR["Metadata Remote
Contrôle distant"]
end
subgraph video[Streaming Vidéo]
JF["Jellyfin
Serveur Média + iGPU"]
TMM["Tiny Media Manager
Gestion métadonnées"]
JFS["Jellystat
Statistiques"]
end
subgraph livres[Gestion Livres]
BL["BookLore
Lecteur moderne"]
BLDB[("MariaDB
Base BookLore")]
end
subgraph analytics[Analytics & Scrobbling]
MS["Multi-Scrobbler
Collecteur"]
MAL["Maloja
Analytics"]
end
subgraph stockage[Stockage]
MUSIC["/mnt/media/musics"]
BOOKS["/mnt/media/books"]
VIDEOS["/mnt/media/videos"]
end
NAV -.->|Scrobble| MS
MS -->|Store| MAL
BL -->|Database| BLDB
JFS -.->|Stats API| JF
NAV -->|Read| MUSIC
MR -->|Read| MUSIC
BL -->|Read| BOOKS
JF -->|Stream| VIDEOS
TMM -->|Manage| VIDEOS
style NAV fill:#bbdefb,stroke:#1976d2,stroke-width:2px,color:#000
style MA fill:#c5e1a5,stroke:#689f38,stroke-width:2px,color:#000
style BL fill:#fff9c4,stroke:#fbc02d,stroke-width:2px,color:#000
style MAL fill:#f8bbd0,stroke:#c2185b,stroke-width:2px,color:#000
style BLDB fill:#b2dfdb,stroke:#00796b,stroke-width:2px,color:#000
style JF fill:#d1c4e9,stroke:#673ab7,stroke-width:2px,color:#000
style TMM fill:#e1bee7,stroke:#9c27b0,stroke-width:2px,color:#000
style JFS fill:#b3e5fc,stroke:#0288d1,stroke-width:2px,color:#000
Légende :
- Navidrome : Serveur de streaming musical compatible protocole Subsonic
- Music Assistant : Hub musical multi-room avec intégration Home Assistant (automatisations, contrôle vocal)
- Jellyfin : Serveur de streaming vidéo avec transcodage matériel iGPU Intel
- Tiny Media Manager : Gestionnaire de métadonnées pour films et séries TV
- Jellystat : Outil d’analyse et de statistiques pour Jellyfin
- BookLore : Gestionnaire et lecteur d’ebooks moderne avec base de données
- Maloja : Analytics d’écoute type Last.fm auto-hébergé
- Multi-Scrobbler : Pont de synchronisation entre Navidrome et Maloja
Services composant la stack #
| Service | Rôle | Port(s) | Image Docker |
|---|---|---|---|
| Navidrome | Serveur de streaming musical (Subsonic API) | 4533 | deluan/navidrome:latest |
| Music Assistant | Hub musical multi-room + intégration Home Assistant | 8095 | ghcr.io/music-assistant/server:latest |
| Jellyfin | Serveur de streaming vidéo (transcodage iGPU) | 8096, 7359/udp | jellyfin/jellyfin |
| Tiny Media Manager | Gestion métadonnées films/séries | 5900 (VNC), 4000 | tinymediamanager/tinymediamanager:latest |
| Jellystat | Statistiques et analytics Jellyfin | 3000 | cyfershepard/jellystat:latest |
| BookLore | Gestionnaire et lecteur d’ebooks | 6060 | booklore/booklore:latest |
| BookLore-DB | Base de données MariaDB pour BookLore | - | lscr.io/linuxserver/mariadb:11.4.5 |
| Maloja | Analytics et statistiques d’écoute | 42010 | krateng/maloja:latest |
| Multi-Scrobbler | Synchronisation scrobbling Navidrome → Maloja | 9078 | foxxmd/multi-scrobbler |
| Metadata Remote | Contrôle distant des métadonnées musicales | 8338 | ghcr.io/wow-signal-dev/metadata-remote:latest |
Architecture de stockage (Perfect Homelab) #
graph TB
subgraph proxmox["Hote Proxmox"]
DISK1["Disque 1
/mnt/data01"]
DISK2["Disque 2
/mnt/data02"]
DISK3["Disque 3
/mnt/data03"]
DISK1 --> MFS["MergerFS Pool
/mnt/storage"]
DISK2 --> MFS
DISK3 --> MFS
MFS --> MEDIA["/mnt/storage/media"]
end
subgraph lxc["Conteneur LXC 140"]
BIND["Bind Mount
/mnt/media"]
BIND --> MUSICS["/mnt/media/musics"]
BIND --> BOOKS["/mnt/media/books"]
BIND --> VIDEOS["/mnt/media/videos"]
MUSICS --> NAV["Navidrome"]
BOOKS --> BL["BookLore"]
VIDEOS --> JF["Jellyfin"]
end
MEDIA -.->|"pct set 140 -mp0"| BIND
style proxmox fill:#e3f2fd,stroke:#1976d2,stroke-width:3px,color:#000
style lxc fill:#f1f8e9,stroke:#689f38,stroke-width:3px,color:#000
style MFS fill:#fff9c4,stroke:#f57c00,stroke-width:2px,color:#000
style BIND fill:#ffe0b2,stroke:#e64a19,stroke-width:2px,color:#000
style MEDIA fill:#fff3e0,stroke:#ff6f00,stroke-width:2px,color:#000
Avantages de cette architecture :
| Caractéristique | Bénéfice |
|---|---|
| Bind mounts LXC | Accès disque direct = performance native |
| Pool MergerFS | Agrégation flexible de plusieurs disques |
| Pas de NFS/SMB | Élimination de la latence réseau |
| Extensibilité | Ajoutez des disques sans réorganiser les données |
| Simplicité | Un seul point de montage /mnt/media dans le conteneur |
Référence : Cette architecture de stockage a été détaillée dans Perfect Homelab E06 : Post-Installation [Données et stockage], où MergerFS et SnapRAID sont configurés sur l’hôte Proxmox en baremetal.
Le bind mount pct set 140 -mp0 /mnt/storage/media,mp=/mnt/media configure un montage transparent : le conteneur LXC voit /mnt/media comme un système de fichiers local, alors qu’il accède directement au pool MergerFS de l’hôte.
Flux de données #
sequenceDiagram
participant User as Utilisateur
participant Client as Client Subsonic
participant NAV as Navidrome
participant MS as Multi-Scrobbler
participant MAL as Maloja
participant MUSIC as Stockage Musical
User->>Client: Lecture d'un titre
Client->>NAV: Requête API Subsonic
NAV->>MUSIC: Récupération fichier audio
MUSIC-->>NAV: Stream audio
NAV-->>Client: Flux audio
NAV->>MS: Notification lecture
MS->>MAL: Scrobble écoute
MAL-->>MS: Confirmation
MS-->>NAV: OK
Le flux de données suit un parcours optimisé : l’utilisateur accède à sa musique via un client compatible Subsonic (mobile ou web), Navidrome diffuse le contenu depuis le pool MergerFS (monté via bind mount), et chaque écoute est automatiquement enregistrée dans Maloja via Multi-Scrobbler pour générer des statistiques détaillées. De même, Jellyfin accède aux vidéos et BookLore aux livres numériques directement depuis ce stockage unifié, garantissant des performances optimales grâce à l’accès disque direct sans couche réseau.
📋 Prérequis techniques #
Logiciels requis #
- Docker : version 24.0+ Installer Docker
- Docker Compose : version 2.0+ (inclus avec Docker Desktop)
- Git : pour récupérer les fichiers de configuration (optionnel)
- Proxmox avec MergerFS : pool de stockage unifié configuré sur l’hôte (voir Perfect Homelab E06)
Connaissances recommandées #
Configuration minimale #
| Composant | Spécification |
|---|---|
| CPU | 2 cœurs (4 cœurs recommandés pour le transcodage) |
| RAM | 2 Go minimum (4 Go recommandés) |
| Disque | 10 Go pour les conteneurs + espace pour vos médias |
| Système | Linux (Ubuntu 20.04+, Debian 11+) ou système compatible Docker |
Préparation du stockage #
Vous devez disposer de :
- Un répertoire contenant vos fichiers musicaux :
/mnt/media/musics(à adapter) - Un répertoire contenant vos livres numériques :
/mnt/media/books(à adapter) - Un répertoire contenant vos films et séries :
/mnt/media/videos(à adapter)
/mnt/storage/media) de l’hôte Proxmox, monté dans le conteneur LXC via bind mount. Les médias sont directement accessibles depuis le stockage unifié sans passer par NFS/SMB.
📁 Structure du projet #
Voici l’arborescence complète du projet :
mediaserver-stack/
├── docker-compose.yml # Orchestration principale (include)
├── .env # Variables d'environnement
│
├── navidrome/
│ ├── docker-compose.yml # Configuration Navidrome
│ └── data/ # Base de données Navidrome
│ └── .gitkeep
│
├── music-assistant/
│ ├── docker-compose.yml # Configuration Music Assistant
│ └── data/ # Données Music Assistant
│ └── .gitkeep
│
├── jellyfin/
│ ├── docker-compose.yml # Configuration Jellyfin
│ ├── config/ # Configuration et bibliothèques
│ └── cache/ # Cache métadonnées
│ └── .gitkeep
│
├── tinymediamanager/
│ ├── docker-compose.yml # Configuration Tiny Media Manager
│ └── data/ # Configuration et cache TMM
│ └── .gitkeep
│
├── jellystat/
│ ├── docker-compose.yml # Configuration Jellystat
│ └── data/ # Sauvegardes base de données
│ └── .gitkeep
│
├── booklore/
│ ├── docker-compose.yml # Configuration BookLore + MariaDB
│ ├── data/ # Données BookLore
│ ├── bookdrop/ # Dépôt de livres à importer
│ └── mariadb/ # Base de données MariaDB
│ └── .gitkeep
│
├── scrobbler-analytics/
│ ├── docker-compose.yml # Multi-Scrobbler + Maloja
│ ├── multi-scrobbler/
│ │ └── config.json # Configuration du scrobbling
│ └── maloja/ # Données Maloja
│ └── .gitkeep
│
└── metadata-remote/
└── docker-compose.yml # Configuration Metadata Remote
Fichiers clés #
| Fichier | Description |
|---|---|
| docker-compose.yml | Fichier principal orchestrant tous les sous-stacks via include |
| .env | Variables d’environnement (mots de passe, clés API) |
| navidrome/docker-compose.yml | Configuration du serveur de streaming musical |
| booklore/docker-compose.yml | Configuration du gestionnaire d’ebooks et sa base MariaDB |
| scrobbler-analytics/docker-compose.yml | Configuration du système de scrobbling et analytics |
| scrobbler-analytics/multi-scrobbler/config.json | Connexion Navidrome ↔ Maloja |
data/, mariadb/ et maloja/ sont exclus du versioning Git (fichiers .gitkeep uniquement). Vos données personnelles et configurations sensibles restent locales.
⚙️ Configuration des services #
Service 1 : Navidrome - Serveur de streaming musical #
Rôle et responsabilités #
Navidrome indexe votre bibliothèque musicale, extrait les métadonnées (tags ID3, pochettes), organise votre collection par artistes/albums/genres et diffuse vos morceaux à la demande. Compatible avec l’écosystème Subsonic, il fonctionne avec une large gamme de clients (DSub, Symfonium, Sonixd, Play:Sub, etc.). Il intègre également le transcodage à la volée pour adapter le débit selon la connexion.
Configuration Docker Compose #
services:
navidrome:
container_name: navidrome
image: deluan/navidrome:latest
user: 1000:1000 # UID:GID de l'utilisateur hôte
restart: unless-stopped
ports:
- 4533:4533 # Port web et API Subsonic
volumes:
- ./data:/data # Base de données et cache
- /mnt/media/musics:/music:ro # Bibliothèque musicale (lecture seule)
environment:
- ND_SCANSCHEDULE=1h # Scan automatique toutes les heures
- ND_LOGLEVEL=info
- ND_SESSIONTIMEOUT=24h # Durée de session 24h
- ND_DEFAULTLANGUAGE=fr # Interface en français
- ND_DEFAULTTHEME=Spotify-ish
- ND_ENABLEDOWNLOADS=false # Désactive les téléchargements
- ND_ENABLETRANSCODINGCONFIG=true
- ND_TRANSCODINGCACHESIZE=1024MB
- ND_AUTOIMPORTPLAYLISTS=false
networks:
- mediaserver
Variables d’environnement principales #
| Variable | Description | Valeur par défaut | Obligatoire |
|---|---|---|---|
| ND_SCANSCHEDULE | Fréquence du scan de la bibliothèque | 1h | Non |
| ND_LOGLEVEL | Niveau de log (error, info, debug) | info | Non |
| ND_SESSIONTIMEOUT | Durée de validité de la session | 24h | Non |
| ND_DEFAULTLANGUAGE | Langue de l’interface | en | Non |
| ND_ENABLETRANSCODINGCONFIG | Active la configuration du transcodage | true | Non |
| ND_TRANSCODINGCACHESIZE | Taille du cache de transcodage | 1024MB | Non |
ND_ENABLETRANSCODINGCONFIG=false.
Volumes et persistance #
./data: Contient la base de données SQLite de Navidrome (artistes, albums, playlists, utilisateurs)/mnt/media/musics: Montage en lecture seule de votre bibliothèque musicale (adapté au chemin de votre stockage)
Dépendances #
Navidrome fonctionne de manière autonome et n’a pas de dépendances directes. Il peut cependant être couplé avec Multi-Scrobbler pour le tracking des écoutes.
Service 2 : Music Assistant - Contrôle multi-room et intégration Home Assistant #
Rôle et responsabilités #
Music Assistant agit comme un hub central pour gérer et diffuser votre musique sur différents équipements : enceintes connectées (Chromecast, AirPlay, Sonos), serveurs audio (Snapcast, DLNA), ou intégrations domotiques. Son rôle principal dans cette stack est de faciliter l’accès à la bibliothèque musicale Navidrome et piloter l’écoute de la musique via Home Assistant.
Il supporte le streaming haute résolution et le regroupement d’enceintes en zones synchronisées.
Intégration Home Assistant : Music Assistant s’intègre nativement avec Home Assistant pour créer des automatisations musicales avancées : réveil en musique, ambiances selon les scénarios, contrôle vocal via Alexa/Google Assistant, etc.
L’intégration complète de Music Assistant avec Home Assistant fera l’objet d’un prochain article de la série Perfect Homelab, détaillant la configuration des automatisations, des lecteurs multi-room et des scénarios domotiques musicaux.
Configuration Docker Compose #
services:
music-assistant:
container_name: music-assistant
image: ghcr.io/music-assistant/server:latest
restart: unless-stopped
network_mode: host # Nécessaire pour la découverte réseau (mDNS)
volumes:
- ./data:/data/ # Configuration et cache
environment:
- LOG_LEVEL=info
Variables d’environnement principales #
| Variable | Description | Valeur par défaut | Obligatoire |
|---|---|---|---|
| LOG_LEVEL | Niveau de log | info | Non |
network_mode: host pour permettre la découverte automatique des équipements réseau (mDNS, SSDP). Ce mode expose tous les ports de l’hôte, pensez à sécuriser l’accès avec un firewall.
Volumes et persistance #
./data: Configuration de Music Assistant, cache des pochettes et métadonnées
Service 3 : BookLore - Gestionnaire d’ebooks moderne #
Rôle et responsabilités #
BookLore offre une interface web élégante pour gérer et lire vos livres numériques. Il supporte EPUB, PDF, MOBI, CBZ/CBR et intègre un lecteur web performant avec sauvegarde de progression, annotations et personnalisation. Il utilise une base de données MariaDB pour stocker les métadonnées et l’historique de lecture.
Configuration Docker Compose #
services:
booklore:
container_name: booklore
image: booklore/booklore:latest
restart: unless-stopped
ports:
- 6060:6060 # Interface web BookLore
depends_on:
booklore-db:
condition: service_healthy # Attend que MariaDB soit prêt
volumes:
- ./data:/app/data # Données BookLore
- ./bookdrop:/bookdrop # Dossier de dépôt pour import automatique
- /mnt/media/books:/books # Bibliothèque de livres
environment:
- BOOKLORE_PORT=6060
- DATABASE_URL=${DATABASE_URL}
- DATABASE_USERNAME=${DB_USER}
- DATABASE_PASSWORD=${DB_PASSWORD}
- USER_ID=1000
- GROUP_ID=1000
- TZ=Europe/Paris
networks:
- mediaserver
Variables d’environnement principales #
| Variable | Description | Valeur par défaut | Obligatoire |
|---|---|---|---|
| BOOKLORE_PORT | Port d’écoute de l’application | 6060 | Non |
| DATABASE_URL | URL JDBC de connexion MariaDB | - | Oui |
| DATABASE_USERNAME | Utilisateur de la base | - | Oui |
| DATABASE_PASSWORD | Mot de passe de la base | - | Oui |
| USER_ID / GROUP_ID | UID/GID pour les permissions fichiers | 1000 | Non |
| TZ | Fuseau horaire | Europe/Paris | Non |
Volumes et persistance #
./data: Données applicatives BookLore./bookdrop: Dossier de dépôt pour importer automatiquement de nouveaux livres/mnt/media/books: Bibliothèque de livres numériques
Service 4 : BookLore-DB - Base de données MariaDB #
Rôle et responsabilités #
Ce conteneur MariaDB (version 11.4.5) stocke toutes les données structurées de BookLore : catalogue des livres, métadonnées extraites, progression de lecture, annotations utilisateurs et configuration applicative. Un healthcheck garantit que la base est opérationnelle avant le démarrage de BookLore.
Configuration Docker Compose #
services:
booklore-db:
container_name: booklore-db
image: lscr.io/linuxserver/mariadb:11.4.5
restart: unless-stopped
volumes:
- ./mariadb/config:/config # Données MariaDB
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${DB_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
- PUID=1000
- PGID=1000
- TZ=Europe/Paris
healthcheck:
test: [ "CMD", "mariadb-admin", "ping", "-h", "localhost" ]
interval: 5s
timeout: 5s
retries: 10
networks:
- mediaserver
Variables d’environnement principales #
| Variable | Description | Valeur par défaut | Obligatoire |
|---|---|---|---|
| MYSQL_ROOT_PASSWORD | Mot de passe root MariaDB | - | Oui |
| MYSQL_DATABASE | Nom de la base à créer | - | Oui |
| MYSQL_USER | Utilisateur applicatif | - | Oui |
| MYSQL_PASSWORD | Mot de passe utilisateur | - | Oui |
Volumes et persistance #
./mariadb/config: Fichiers de configuration et données MariaDB (bases, tables, index)
Service 5 : Maloja - Analytics d’écoute #
Rôle et responsabilités #
Maloja enregistre toutes vos écoutes musicales (scrobbles) et génère des statistiques détaillées : tops artistes/albums/titres, graphiques d’écoute, découvertes musicales, etc. Il offre une API compatible avec les clients Last.fm tout en préservant votre vie privée puisque les données restent sur votre serveur.
Configuration Docker Compose #
services:
maloja:
container_name: maloja
image: krateng/maloja:latest
restart: unless-stopped
ports:
- 42010:42010 # Interface web Maloja
volumes:
- ./maloja:/data # Base de données Maloja
environment:
- MALOJA_FORCE_PASSWORD=${MALOJA_FORCE_PASSWORD}
- MALOJA_DATA_DIRECTORY=/data
networks:
- mediaserver
Variables d’environnement principales #
| Variable | Description | Valeur par défaut | Obligatoire |
|---|---|---|---|
| MALOJA_FORCE_PASSWORD | Mot de passe d’administration | - | Oui |
| MALOJA_DATA_DIRECTORY | Répertoire de données | /data | Non |
Volumes et persistance #
./maloja: Base de données des scrobbles et configuration
Service 6 : Multi-Scrobbler - Synchronisation des écoutes #
Rôle et responsabilités #
Multi-Scrobbler surveille vos écoutes sur Navidrome (via l’API Subsonic) et les transmet à Maloja pour archivage et génération de statistiques. Il supporte plusieurs sources et destinations simultanément, permettant de centraliser le tracking depuis différents lecteurs vers plusieurs services d’analytics.
Configuration Docker Compose #
services:
multi-scrobbler:
container_name: multi-scrobbler
image: foxxmd/multi-scrobbler
restart: unless-stopped
ports:
- 9078:9078 # Interface web de monitoring
volumes:
- ./multi-scrobbler:/config # Configuration JSON
environment:
- BASE_URL=http://10.10.20.41:9078 # URL publique du scrobbler
- PUID=1000
- PGID=1000
- TZ=Europe/Paris
networks:
- mediaserver
Variables d’environnement principales #
| Variable | Description | Valeur par défaut | Obligatoire |
|---|---|---|---|
| BASE_URL | URL d’accès au scrobbler | - | Non |
| PUID / PGID | UID/GID pour permissions | 1000 | Non |
| TZ | Fuseau horaire | Europe/Paris | Non |
BASE_URL doit être accessible depuis Navidrome si vous utilisez les webhooks. Sinon, le polling API Subsonic est utilisé.
Configuration du scrobbling #
Le fichier ./multi-scrobbler/config.json configure les sources (Navidrome) et destinations (Maloja) :
{
"sources": [
{
"type": "subsonic",
"name": "Navidrome",
"data": {
"url": "http://navidrome:4533",
"user": "navidrome_user",
"password": "navidrome_password"
}
}
],
"clients": [
{
"type": "maloja",
"name": "Allfabox Maloja",
"data": {
"url": "http://maloja:42010",
"apiKey": "maloja_api_key_here"
}
}
]
}
navidrome_user, navidrome_password et maloja_api_key_here par vos vraies informations d’authentification.
Volumes et persistance #
./multi-scrobbler: Fichier de configurationconfig.json
Service 7 : Metadata Remote - Contrôle distant des métadonnées #
Rôle et responsabilités #
Ce service expose une API web permettant de visualiser et éditer les tags ID3 de votre bibliothèque musicale depuis n’importe quel navigateur. Utile pour corriger des métadonnées sans accéder directement au serveur ou utiliser un logiciel lourd.
Configuration Docker Compose #
services:
metadata-remote:
container_name: metadata-remote
image: ghcr.io/wow-signal-dev/metadata-remote:latest
restart: unless-stopped
ports:
- 8338:8338 # Interface web
volumes:
- /mnt/media/musics:/music # Bibliothèque musicale
environment:
- PUID=1000
- PGID=1000
networks:
- mediaserver
Variables d’environnement principales #
| Variable | Description | Valeur par défaut | Obligatoire |
|---|---|---|---|
| PUID / PGID | UID/GID pour permissions | 1000 | Non |
Volumes et persistance #
/mnt/media/musics: Bibliothèque musicale (montage en lecture/écriture pour édition des tags)
Service 8 : Jellyfin - Serveur de streaming vidéo #
Rôle et responsabilités #
Jellyfin transforme votre bibliothèque de films et séries en plateforme de streaming personnelle, alternative libre à Plex ou Emby. Il organise automatiquement vos médias, récupère les métadonnées et pochettes depuis TMDB/TheTVDB, et transcode à la volée pour s’adapter à vos appareils. Dans cette configuration, le transcodage matériel via iGPU Intel permet de gérer plusieurs flux simultanés sans saturer le CPU.
Configuration Docker Compose #
services:
jellyfin:
container_name: jellyfin
image: jellyfin/jellyfin
network_mode: host # Nécessaire pour découverte DLNA/UPnP
restart: unless-stopped
group_add:
- 104 # Groupe render pour accès GPU
devices:
- /dev/dri/renderD128:/dev/dri/renderD128 # iGPU Intel
volumes:
- ./config:/config # Configuration Jellyfin
- ./cache:/cache # Cache métadonnées
- /mnt/media/videos:/media # Bibliothèque vidéo
- /dev/shm/transcodes:/cache/transcodes # Transcodage en RAM
environment:
- JELLYFIN_PublishedServerUrl=http://jellyfin.mydomain.com
extra_hosts:
- host.docker.internal:host-gateway
Variables d’environnement principales #
| Variable | Description | Valeur par défaut | Obligatoire |
|---|---|---|---|
| JELLYFIN_PublishedServerUrl | URL publique du serveur | - | Non (recommandé) |
Important - Configuration iGPU :
- Le paramètre
group_add: - 104correspond au GID du grouperendervérifié lors de la configuration LXC - Le périphérique
/dev/dri/renderD128est monté depuis l’hôte Proxmox via la configuration LXC - Si votre système utilise un GID différent, ajustez cette valeur après avoir vérifié avec
getent group render
Volumes et persistance #
./config: Configuration Jellyfin (utilisateurs, bibliothèques, plugins)./cache: Cache des métadonnées et images/mnt/media/videos: Bibliothèque vidéo (films, séries, etc.)/dev/shm/transcodes: Stockage temporaire en RAM pour transcodage (améliore les performances et réduit l’usure SSD)
/dev/shm utilise la RAM comme stockage temporaire pour les fichiers transcodés, éliminant les I/O disque et accélérant significativement le transcodage. Assurez-vous d’avoir suffisamment de RAM (8 Go recommandés).
Configuration du transcodage matériel #
Une fois Jellyfin démarré, activez le transcodage iGPU :
- Accédez à Dashboard → Playback → Transcoding
- Sélectionnez Hardware acceleration :
Intel Quick Sync (QSV) - Cochez les codecs supportés : H.264, HEVC (H.265), VP9
- Appliquez et redémarrez Jellyfin
Vérification :
Prérequis : Installez d’abord l’outil intel-gpu-tools :
Dans le conteneur LXC :
apt install intel-gpu-tools
Sur l’hôte Proxmox (recommandé) :
apt install intel-gpu-tools
Vérifier l’utilisation GPU pendant un transcodage actif :
# Depuis le conteneur LXC
docker exec jellyfin intel_gpu_top
# OU depuis l'hôte Proxmox (fonctionne également)
intel_gpu_top
intel_gpu_top depuis l’hôte Proxmox pour monitorer l’utilisation GPU de Jellyfin. Cela évite d’installer le paquet dans le conteneur et permet de surveiller tous les conteneurs LXC utilisant l’iGPU simultanément.
Codecs supportés par iGPU Intel (génération 7+) :
- Décodage : H.264, HEVC, VP9, AV1 (gen 11+)
- Encodage : H.264, HEVC
Dépendances et notes #
- Jellyfin fonctionne en mode
network_mode: hostpour la découverte réseau (DLNA, Chromecast) - Les ports principaux sont 8096 (HTTP) et 7359/udp (découverte)
- Aucune dépendance avec les autres services de la stack (fonctionne de manière autonome)
Service 9 : Tiny Media Manager - Gestion des métadonnées #
Rôle et responsabilités #
TMM (Tiny Media Manager) scanne votre bibliothèque vidéo, identifie automatiquement les films et séries via leurs noms de fichiers, puis récupère les métadonnées complètes depuis TMDB, IMDB, TheTVDB, etc. Il génère les fichiers .nfo compatibles avec Jellyfin/Kodi et télécharge les visuels (posters, fanarts, logos). L’interface est accessible via VNC ou navigateur web.
Configuration Docker Compose #
services:
tinymediamanager:
container_name: tinymediamanager
image: tinymediamanager/tinymediamanager:latest
restart: unless-stopped
ports:
- 5900:5900 # VNC (accès distant)
- 4000:4000 # Interface web
volumes:
- ./data:/data # Configuration TMM
- /mnt/media/videos/movies:/media/movies
- /mnt/media/videos/tvshows:/media/tv_shows
- /mnt/media/videos/kids:/media/kids
environment:
- USER_ID=1000
- GROUP_ID=1000
- ALLOW_DIRECT_VNC=true
- LC_ALL=fr_FR.UTF-8 # Interface en français
- LANG=fr_FR.UTF-8
- LC_TIME=C.UTF-8
- TZ=Europe/Paris
- PASSWORD=${VNC_PASSWORD} # Mot de passe VNC
networks:
- mediaserver
Variables d’environnement principales #
| Variable | Description | Valeur par défaut | Obligatoire |
|---|---|---|---|
| USER_ID / GROUP_ID | UID/GID pour permissions fichiers | 1000 | Non |
| ALLOW_DIRECT_VNC | Active l’accès VNC direct | false | Non |
| LC_ALL / LANG | Localisation interface | en_US.UTF-8 | Non |
| PASSWORD | Mot de passe VNC | - | Oui |
| TZ | Fuseau horaire | UTC | Non |
VNC_PASSWORD dans le fichier .env pour sécuriser l’accès distant.
Volumes et persistance #
./data: Configuration TMM (sources, scrapers, cache)/mnt/media/videos/movies: Bibliothèque de films/mnt/media/videos/tvshows: Bibliothèque de séries TV/mnt/media/videos/kids: Bibliothèque contenu jeunesse
.nfo et télécharger les visuels. Assurez-vous que l’UID 1000 a les permissions appropriées.
Accès à l’interface #
Via navigateur web (recommandé) :
http://10.10.20.40:4000
Via client VNC :
# Exemple avec TigerVNC
vncviewer 10.10.20.40:5900
Workflow typique #
- Ajoutez les sources : Configurez les chemins
/media/movies,/media/tv_showsdans TMM - Scannez la bibliothèque : TMM détecte les nouveaux fichiers
- Récupération métadonnées : Sélectionnez les médias et lancez le scraping (TMDB, IMDB)
- Génération NFO : TMM crée les fichiers
.nfoet télécharge les visuels - Refresh Jellyfin : Actualisez la bibliothèque Jellyfin pour intégrer les nouvelles métadonnées
Astuce : Organisez vos fichiers selon la convention de nommage Jellyfin/Kodi :
/movies/Film (2023)/Film (2023).mkv
/tvshows/Serie/Season 01/Serie - S01E01.mkv
TMM reconnaîtra automatiquement la structure et remplira les métadonnées correctement.
Dépendances #
- Aucune dépendance directe avec Jellyfin, mais fonctionne en complémentarité
- TMM prépare les métadonnées que Jellyfin consomme ensuite
Service 10 : Jellystat - Statistiques Jellyfin #
Rôle et responsabilités #
Jellystat se connecte à votre serveur Jellyfin pour collecter les données de lecture (films visionnés, séries regardées, utilisateurs actifs, tendances de visionnage). Il offre une interface web moderne avec tableaux de bord, graphiques et rapports détaillés sur l’activité de votre bibliothèque vidéo. Contrairement aux statistiques natives de Jellyfin, Jellystat conserve un historique complet et propose des visualisations avancées.
Configuration Docker Compose #
services:
jellystat:
container_name: jellystat
image: cyfershepard/jellystat:latest
restart: unless-stopped
ports:
- 3000:3000 # Interface web Jellystat
volumes:
- ./data:/app/backend/backup-data # Sauvegardes base de données
environment:
- POSTGRES_DB=jfstat # Base de données PostgreSQL
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_IP=10.10.20.20 # IP du serveur PostgreSQL
- POSTGRES_PORT=5432
- JWT_SECRET=${JELLYSTAT_JWT_SECRET} # Clé secrète JWT
- TZ=Europe/Paris
networks:
- mediaserver
Variables d’environnement principales #
| Variable | Description | Valeur par défaut | Obligatoire |
|---|---|---|---|
| POSTGRES_DB | Nom de la base de données | jfstat | Non |
| POSTGRES_USER | Utilisateur PostgreSQL | - | Oui |
| POSTGRES_PASSWORD | Mot de passe PostgreSQL | - | Oui |
| POSTGRES_IP | Adresse IP du serveur PostgreSQL | - | Oui |
| POSTGRES_PORT | Port PostgreSQL | 5432 | Non |
| JWT_SECRET | Clé secrète pour authentification JWT | - | Oui |
| TZ | Fuseau horaire | UTC | Non |
10.10.20.20:5432. Adaptez POSTGRES_IP selon votre configuration. Si vous n’avez pas de serveur PostgreSQL, déployez-en un via Docker Compose ou utilisez une instance existante de votre infrastructure.
Volumes et persistance #
./data: Sauvegardes automatiques de la base de données PostgreSQL
./data contient uniquement les backups générés par Jellystat pour récupération en cas de problème.
Accès à l’interface #
http://10.10.20.40:3000
Configuration initiale :
-
Créer un compte administrateur Jellystat
- Lors de la première connexion à
http://10.10.20.40:3000, créez un compte administrateur
- Lors de la première connexion à
-
Générer une clé API dans Jellyfin (prérequis obligatoire)
Important : Jellystat a besoin d’une clé API Jellyfin pour accéder aux données du serveur. Cette clé doit être générée depuis l’interface d’administration de Jellyfin.- Connectez-vous à Jellyfin en tant qu’administrateur :
http://10.10.20.40:8096 - Accédez au Dashboard (coin supérieur droit → icône engrenage)
- Cliquez sur Advanced (Avancé) dans le menu de gauche
- Sélectionnez API Keys (Clés API)
- Cliquez sur + (Ajouter) pour créer une nouvelle clé
- Donnez un nom descriptif :
Jellystat - Copiez la clé générée
- Connectez-vous à Jellyfin en tant qu’administrateur :
-
Connecter Jellystat à Jellyfin
- Retournez dans l’interface Jellystat
- Ajoutez votre serveur Jellyfin avec les informations suivantes :
- URL Jellyfin :
http://10.10.20.40:8096(ouhttp://jellyfin:8096si utilisation du réseau Docker bridge) - Clé API : Collez la clé API générée à l’étape 2
- URL Jellyfin :
- Cliquez sur Connecter ou Valider
-
Vérification
- Jellystat commence immédiatement à collecter les données d’activité
- Les statistiques des lectures passées sont importées
- Les nouveaux visionnages sont synchronisés automatiquement toutes les heures
Workflow typique #
- Installation et configuration : Première connexion et ajout du serveur Jellyfin
- Collecte automatique : Jellystat synchronise les données toutes les heures
- Consultation dashboards : Visualisez les films/séries populaires, temps de visionnage, utilisateurs actifs
- Rapports personnalisés : Créez des rapports sur périodes spécifiques (mois, année)
Dépendances #
graph LR
A[Jellystat] --> B[Jellyfin]
A --> C[(PostgreSQL)]
style A fill:#e1f5ff,stroke:#0288d1,stroke-width:2px,color:#000
style B fill:#fff3e0,stroke:#f57c00,stroke-width:2px,color:#000
style C fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px,color:#000
- Jellyfin : Source des données de visionnage (connexion via API)
- PostgreSQL : Stockage des statistiques et historique (externe requis)
🚀 Déploiement étape par étape #
Étape 1 : Préparation de l’environnement #
1.1 Créer la structure de dossiers #
# Crée la structure complète du projet
mkdir -p mediaserver-stack/{navidrome,music-assistant,jellyfin,tinymediamanager,jellystat,booklore,scrobbler-analytics,metadata-remote}
mkdir -p mediaserver-stack/navidrome/data
mkdir -p mediaserver-stack/music-assistant/data
mkdir -p mediaserver-stack/jellyfin/{config,cache}
mkdir -p mediaserver-stack/tinymediamanager/data
mkdir -p mediaserver-stack/jellystat/data
mkdir -p mediaserver-stack/booklore/{data,bookdrop,mariadb}
mkdir -p mediaserver-stack/scrobbler-analytics/{maloja,multi-scrobbler}
cd mediaserver-stack
1.2 Vérifier les montages de médias #
# Vérifie que les répertoires de médias sont accessibles
ls -lh /mnt/media/musics
ls -lh /mnt/media/books
ls -lh /mnt/media/videos
/mnt/storage/media sur l’hôte Proxmox.
1.3 Configuration des variables d’environnement #
# Crée le fichier .env depuis l'exemple
cat > .env << 'EOF'
COMPOSE_PROJECT_NAME=mediaserver
# MALOJA
MALOJA_FORCE_PASSWORD="VotreMotDePasseSecurisé"
MALOJA_API_KEY="VotreCléAPIAleatoire"
# TINYMEDIAMANAGER
VNC_PASSWORD="MotDePasseVNCSecurisé"
# JELLYSTAT
POSTGRES_USER=jellystat
POSTGRES_PASSWORD="MotDePassePostgreSQLSecurisé"
JELLYSTAT_JWT_SECRET="CléSecrèteJWTAleatoire"
# BOOKLORE
# Database Connection (BookLore)
DATABASE_URL=jdbc:mariadb://booklore-db:3306/booklore
DB_USER=booklore
DB_PASSWORD="MotDePasseBookLoreSecurisé"
# MariaDB Container Settings
MYSQL_ROOT_PASSWORD="MotDePasseRootMariaDB"
MYSQL_DATABASE=booklore
EOF
Variables à personnaliser obligatoirement :
MALOJA_FORCE_PASSWORD: Mot de passe d’administration de MalojaMALOJA_API_KEY: Clé API pour le scrobbling (à générer aléatoirement)VNC_PASSWORD: Mot de passe pour accéder à Tiny Media Manager via VNCPOSTGRES_PASSWORD: Mot de passe de l’utilisateur PostgreSQL pour JellystatJELLYSTAT_JWT_SECRET: Clé secrète JWT pour l’authentification Jellystat (à générer aléatoirement)DB_PASSWORD: Mot de passe de l’utilisateur BookLore dans MariaDBMYSQL_ROOT_PASSWORD: Mot de passe root de MariaDB
openssl rand -base64 32
1.4 Créer les fichiers docker-compose.yml #
Créez chaque fichier docker-compose.yml dans son sous-répertoire respectif en reprenant les configurations détaillées dans la section précédente. Commencez par le fichier principal :
# Fichier principal d'orchestration
cat > docker-compose.yml << 'EOF'
---
include:
- ./navidrome/docker-compose.yml
- ./music-assistant/docker-compose.yml
- ./jellyfin/docker-compose.yml
- ./tinymediamanager/docker-compose.yml
- ./jellystat/docker-compose.yml
- ./scrobbler-analytics/docker-compose.yml
- ./metadata-remote/docker-compose.yml
- ./booklore/docker-compose.yml
networks:
mediaserver:
name: mediaserver
driver: bridge
ipam:
config:
- subnet: 172.18.0.0/16
gateway: 172.18.0.1
EOF
1.5 Configuration Multi-Scrobbler #
# Crée la configuration du scrobbling Navidrome → Maloja
cat > scrobbler-analytics/multi-scrobbler/config.json << 'EOF'
{
"sources": [
{
"type": "subsonic",
"name": "Navidrome",
"data": {
"url": "http://navidrome:4533",
"user": "votre_utilisateur_navidrome",
"password": "votre_mot_de_passe_navidrome"
}
}
],
"clients": [
{
"type": "maloja",
"name": "Maloja Analytics",
"data": {
"url": "http://maloja:42010",
"apiKey": "VotreCléAPIAleatoire"
}
}
]
}
EOF
Étape 2 : Lancement de la stack #
# Lance tous les services en arrière-plan
docker compose up -d
Que se passe-t-il ?
graph TD
A[docker compose up -d] --> B[Création réseau mediaserver]
B --> C[Pull des images Docker]
C --> D[Démarrage booklore-db]
D --> E{Healthcheck MariaDB}
E -->|OK| F[Démarrage booklore]
E -->|Attente| E
C --> G[Démarrage services parallèles]
G --> H[navidrome]
G --> I[maloja]
G --> J[multi-scrobbler]
G --> L[music-assistant]
G --> M[metadata-remote]
G --> O[jellyfin]
G --> P[tinymediamanager]
F --> N[Stack opérationnelle]
H --> N
I --> N
J --> N
L --> N
M --> N
O --> N
P --> N
style B fill:#e3f2fd,stroke:#1976d2,stroke-width:2px,color:#000
style E fill:#fff9c4,stroke:#f57c00,stroke-width:2px,color:#000
style N fill:#c8e6c9,stroke:#388e3c,stroke-width:2px,color:#000
- Docker crée le réseau
mediaserver(172.18.0.0/16) - Les images Docker sont téléchargées si nécessaire
- MariaDB démarre en premier (dépendance de BookLore)
- Le healthcheck vérifie que MariaDB est prêt (jusqu’à 10 tentatives)
- BookLore démarre une fois la base disponible
- Les autres services démarrent en parallèle
- Multi-Scrobbler établit la connexion avec Navidrome et Maloja
Étape 3 : Configuration initiale des services #
3.1 Navidrome - Premier accès #
# Accédez à l'interface web Navidrome
# URL : http://10.10.20.41:4533
Lors du premier accès :
- Créez un compte administrateur (notez bien ces identifiants)
- Navidrome scanne automatiquement
/music - Patientez pendant l’indexation initiale (durée selon la taille de votre bibliothèque)
docker compose logs -f navidrome
3.2 Maloja - Configuration #
# Accédez à Maloja
# URL : http://10.10.20.41:42010
- Connectez-vous avec le mot de passe défini dans
MALOJA_FORCE_PASSWORD - Naviguez dans Settings → API Keys
- Générez une clé API (ou vérifiez que celle du
.envest active) - Copiez cette clé pour la configuration Multi-Scrobbler
3.3 Multi-Scrobbler - Finalisation #
Maintenant que vous avez créé votre compte Navidrome et récupéré la clé API Maloja :
# Édite la configuration du scrobbler
nano scrobbler-analytics/multi-scrobbler/config.json
Mettez à jour avec vos vraies informations :
{
"sources": [
{
"type": "subsonic",
"name": "Navidrome",
"data": {
"url": "http://navidrome:4533",
"user": "admin", # ← Votre utilisateur Navidrome
"password": "votre_mot_de_passe" # ← Votre mot de passe Navidrome
}
}
],
"clients": [
{
"type": "maloja",
"name": "Maloja Analytics",
"data": {
"url": "http://maloja:42010",
"apiKey": "votre_vraie_clé_api" # ← Clé API Maloja
}
}
]
}
Redémarrez Multi-Scrobbler pour appliquer :
docker compose restart multi-scrobbler
3.4 BookLore - Premier accès #
# URL : http://10.10.20.41:6060
- Créez un compte administrateur
- Scannez votre bibliothèque
/books - Déposez de nouveaux livres dans
booklore/bookdrop/pour import automatique
Étape 4 : Vérification de la communication inter-services #
4.1 Test du scrobbling #
# Vérifiez les logs de Multi-Scrobbler
docker compose logs -f multi-scrobbler
Lancez une écoute depuis Navidrome et vérifiez que :
- Multi-Scrobbler détecte l’écoute (log :
Now Playing detected) - Le scrobble est envoyé à Maloja après ~50% du morceau
- L’écoute apparaît dans Maloja (interface web)
✅ Vérification et tests #
Vérifier que tous les services sont démarrés #
# Liste tous les conteneurs de la stack
docker compose ps
Sortie attendue :
NAME IMAGE STATUS PORTS
booklore booklore/booklore:latest Up 5 minutes 0.0.0.0:6060->6060/tcp
booklore-db lscr.io/linuxserver/mariadb:11.4.5 Up 5 minutes
jellyfin jellyfin/jellyfin Up 5 minutes
jellystat cyfershepard/jellystat:latest Up 5 minutes 0.0.0.0:3000->3000/tcp
maloja krateng/maloja:latest Up 5 minutes 0.0.0.0:42010->42010/tcp
metadata-remote ghcr.io/wow-signal-dev/metadata-remote Up 5 minutes 0.0.0.0:8338->8338/tcp
multi-scrobbler foxxmd/multi-scrobbler Up 5 minutes 0.0.0.0:9078->9078/tcp
music-assistant ghcr.io/music-assistant/server:latest Up 5 minutes
navidrome deluan/navidrome:latest Up 5 minutes 0.0.0.0:4533->4533/tcp
tinymediamanager tinymediamanager/tinymediamanager:latest Up 5 minutes 0.0.0.0:4000->4000/tcp, 0.0.0.0:5900->5900/tcp
Tests fonctionnels #
Test 1 : Streaming musical via Navidrome #
# Teste l'API Subsonic (authentification)
curl -u "admin:password" "http://10.10.20.41:4533/rest/ping?v=1.16.1&c=test"
Résultat attendu : Réponse XML contenant <subsonic-response status="ok">
Test 2 : Accès à BookLore #
curl -I http://10.10.20.41:6060
Résultat attendu : HTTP/1.1 200 OK
Test 3 : Accès à Jellyfin #
# Teste l'accès à l'interface web Jellyfin
curl -I http://10.10.20.40:8096
Résultat attendu : HTTP/1.1 200 OK ou redirection 302 Found
/media avec les sous-dossiers appropriés (movies, tvshows, etc.).
Test 4 : Accès à Jellystat #
# Teste l'accès à l'interface web Jellystat
curl -I http://10.10.20.40:3000
Résultat attendu : HTTP/1.1 200 OK
Configuration Jellystat : Lors de la première connexion à Jellystat (http://10.10.20.40:3000) :
- Créez un compte administrateur Jellystat
- Générez une clé API dans Jellyfin :
- Connectez-vous à Jellyfin :
http://10.10.20.40:8096 - Dashboard → Advanced (Avancé) → API Keys (Clés API)
- Cliquez sur + pour créer une nouvelle clé nommée
Jellystat - Copiez la clé (elle ne sera plus visible après fermeture)
- Connectez-vous à Jellyfin :
- Connectez Jellystat à Jellyfin :
- URL Jellyfin :
http://10.10.20.40:8096(ouhttp://jellyfin:8096si réseau bridge) - Collez la clé API générée à l’étape 2
- URL Jellyfin :
- La collecte des statistiques démarre automatiquement après connexion
Test 5 : Vérification du scrobbling #
- Lancez une lecture depuis Navidrome
- Attendez 30 secondes minimum
- Vérifiez dans Maloja (http://10.10.20.41:42010) que l’écoute apparaît
Vérification des logs #
# Logs de tous les services (mode suivi)
docker compose logs -f
# Logs d'un service spécifique
docker compose logs -f navidrome
docker compose logs -f multi-scrobbler
docker compose logs -f booklore
Signaux d’alerte :
Connection refused→ Vérifier que le service cible est démarréAuthentication failed→ Vérifier les identifiants dans les configurationsPermission denied→ Vérifier les UID/GID et permissions des volumes
Test d’import de livre dans BookLore #
# Copie un livre de test dans le bookdrop
cp /chemin/vers/livre.epub booklore/bookdrop/
# Vérifie les logs d'import
docker compose logs -f booklore
Le livre devrait être automatiquement importé et visible dans l’interface BookLore.
🔧 Maintenance et monitoring #
Commandes utiles au quotidien #
Redémarrer un service #
# Redémarre un service spécifique
docker compose restart navidrome
# Redémarre tous les services
docker compose restart
Mettre à jour la stack #
# Récupère les dernières images
docker compose pull
# Reconstruit et redémarre avec les nouvelles images
docker compose up -d --force-recreate
Sauvegarder les données #
# Script de sauvegarde simple
#!/bin/bash
BACKUP_DIR="/backup/mediaserver-$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
# Arrête les services pour cohérence des données
cd ~/mediaserver-stack
docker compose stop
# Sauvegarde les volumes de données
tar -czf "$BACKUP_DIR/navidrome-data.tar.gz" navidrome/data
tar -czf "$BACKUP_DIR/booklore-data.tar.gz" booklore/data booklore/mariadb
tar -czf "$BACKUP_DIR/maloja-data.tar.gz" scrobbler-analytics/maloja
# Sauvegarde la configuration
cp .env "$BACKUP_DIR/"
cp scrobbler-analytics/multi-scrobbler/config.json "$BACKUP_DIR/"
# Redémarre les services
docker compose start
echo "Sauvegarde terminée dans $BACKUP_DIR"
Monitoring des ressources #
# Utilisation CPU/RAM en temps réel
docker stats
# Espace disque des volumes
docker system df -v
Nettoyage et maintenance #
# Supprime les conteneurs arrêtés et images inutilisées
docker system prune -a
Attention : La commande suivante supprime aussi les volumes non utilisés. Utilisez-la avec précaution !
docker system prune -a --volumes
Surveillance de la santé des services #
# Vérification de l'état de santé de MariaDB
docker inspect booklore-db --format='{{.State.Health.Status}}'
Résultat attendu : healthy
🔍 Troubleshooting #
Problème 1 : Navidrome ne trouve pas les fichiers musicaux #
Symptômes :
- Bibliothèque vide dans Navidrome
- Logs :
No music files foundouPermission denied
Causes probables :
- Le montage
/mnt/media/musicsn’est pas accessible - Permissions incorrectes (l’utilisateur 1000:1000 ne peut pas lire les fichiers)
- Aucun fichier musical avec extensions reconnues (.mp3, .flac, .ogg, etc.)
Solutions :
# Vérifiez que le montage existe et contient des fichiers
ls -lah /mnt/media/musics
# Vérifiez les permissions
namei -l /mnt/media/musics
# Ajustez les permissions si nécessaire (exemple)
sudo chown -R 1000:1000 /mnt/media/musics
sudo chmod -R 755 /mnt/media/musics
# Forcez un nouveau scan
docker compose restart navidrome
Problème 2 : BookLore ne se connecte pas à MariaDB #
Symptômes :
- BookLore redémarre en boucle
- Logs :
Connection refusedouAccess denied for user 'booklore'@'...'
Cause probable : Les variables d’environnement de connexion à la base ne correspondent pas entre BookLore et MariaDB.
Solution :
# Vérifiez les variables dans .env
cat .env | grep -E 'DB_|MYSQL_'
# Vérifiez que booklore-db est healthy
docker inspect booklore-db --format='{{.State.Health.Status}}'
# Si unhealthy, consultez les logs MariaDB
docker compose logs booklore-db
# Vérifiez la connexion manuelle
docker compose exec booklore-db mariadb -u booklore -p booklore
# Entrez le mot de passe DB_PASSWORD
Si la connexion manuelle échoue, recréez l’utilisateur :
docker compose exec booklore-db mariadb -u root -p
# Entrez MYSQL_ROOT_PASSWORD
# Dans le shell MariaDB
CREATE USER IF NOT EXISTS 'booklore'@'%' IDENTIFIED BY 'votre_mot_de_passe';
GRANT ALL PRIVILEGES ON booklore.* TO 'booklore'@'%';
FLUSH PRIVILEGES;
EXIT;
# Redémarrez BookLore
docker compose restart booklore
Problème 3 : Multi-Scrobbler ne scrobble pas les écoutes #
Symptômes :
- Écoutes dans Navidrome mais rien dans Maloja
- Logs Multi-Scrobbler :
Authentication failedouConnection timeout
Causes probables :
- Identifiants Navidrome incorrects dans
config.json - Clé API Maloja incorrecte ou expirée
- Services Navidrome/Maloja inaccessibles depuis Multi-Scrobbler
Solutions :
# Vérifiez la configuration
cat scrobbler-analytics/multi-scrobbler/config.json
# Testez la connexion à Navidrome depuis le conteneur
docker compose exec multi-scrobbler curl http://navidrome:4533
# Testez la connexion à Maloja
docker compose exec multi-scrobbler curl http://maloja:42010
# Si les connexions échouent, vérifiez le réseau
docker network inspect mediaserver
# Vérifiez les logs en temps réel
docker compose logs -f multi-scrobbler
"logLevel": "debug" dans config.json puis redémarrez.
Problème 4 : Music Assistant ne découvre pas les équipements #
Symptômes :
- Aucune enceinte Chromecast/AirPlay détectée
- Logs :
mDNS discovery failed
Cause probable : Le mode network_mode: host est requis pour la découverte mDNS, mais peut être bloqué par le firewall.
Solution :
# Vérifiez que Music Assistant est bien en mode host
docker inspect music-assistant --format='{{.HostConfig.NetworkMode}}'
# Résultat attendu : host
# Vérifiez que le firewall autorise mDNS (port UDP 5353)
sudo ufw allow 5353/udp
# Redémarrez le service
docker compose restart music-assistant
Problème 5 : Jellystat ne démarre pas (erreur PostgreSQL) #
Symptômes :
- Jellystat redémarre en boucle
- Logs :
Connection refusedoucould not connect to server
Cause probable : PostgreSQL n’est pas installé ou n’est pas accessible depuis le conteneur Jellystat.
Solutions :
Option 1 : Installer PostgreSQL sur l’hôte Proxmox
# Sur l'hôte Proxmox, installez PostgreSQL
apt update && apt install postgresql postgresql-contrib
# Créez la base de données et l'utilisateur
sudo -u postgres psql
CREATE DATABASE jfstat;
CREATE USER jellystat WITH PASSWORD 'votre_mot_de_passe';
GRANT ALL PRIVILEGES ON DATABASE jfstat TO jellystat;
\q
# Autorisez les connexions depuis le réseau Docker
# Éditez /etc/postgresql/*/main/pg_hba.conf et ajoutez :
host jfstat jellystat 172.18.0.0/16 md5
# Éditez /etc/postgresql/*/main/postgresql.conf
listen_addresses = '*'
# Redémarrez PostgreSQL
systemctl restart postgresql
Option 2 : Ajouter PostgreSQL au docker-compose
# Ajoutez dans jellystat/docker-compose.yml
services:
jellystat-db:
container_name: jellystat-db
image: postgres:16-alpine
restart: unless-stopped
environment:
- POSTGRES_DB=jfstat
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- ./postgres-data:/var/lib/postgresql/data
networks:
- mediaserver
jellystat:
# ... configuration existante
environment:
- POSTGRES_IP=jellystat-db # Modifiez cette ligne
# ... autres variables
depends_on:
- jellystat-db
Diagramme de débogage #
flowchart TD
A[Service ne démarre pas] --> B{Vérifier les logs}
B -->|Port déjà utilisé| C[Port en conflit]
B -->|Permission denied| D[Permissions incorrectes]
B -->|Connection refused| E[Dépendance non démarrée]
B -->|Authentication failed| F[Identifiants incorrects]
C --> G[Modifier le port dans docker-compose.yml]
D --> H[Ajuster UID/GID et permissions volumes]
E --> I[Vérifier depends_on et healthcheck]
F --> J[Corriger .env ou config.json]
G --> K[Redémarrer la stack]
H --> K
I --> K
J --> K
K --> L{Service démarre ?}
L -->|Oui| M[Problème résolu]
L -->|Non| N[Consulter les logs détaillés]
N --> O[Demander de l'aide sur GitHub/forum]
style C fill:#ffcdd2,color:#000
style D fill:#fff3cd,color:#000
style E fill:#ffe0b2,color:#000
style F fill:#f8bbd0,color:#000
style M fill:#c8e6c9,color:#000
FAQ #
DATABASE_URL en JDBC PostgreSQL : jdbc:postgresql://booklore-db:5432/booklore et remplacez l’image MariaDB par une image PostgreSQL.
ND_ENABLETRANSCODINGCONFIG=true). Configurez les profils dans l’interface web (Settings → Transcoding) pour définir les débits selon les clients.
ports:) des services qui ne doivent plus être exposés directement.
⚡ Optimisations et bonnes pratiques #
Sécurité #
1. Gestion des secrets #
docker-compose.yml
# Exemple : générer des secrets robustes
openssl rand -base64 32 > secrets/db_password.txt
openssl rand -base64 32 > secrets/maloja_api_key.txt
# Protéger les fichiers de secrets
chmod 600 secrets/*
Ajoutez secrets/ à .gitignore pour éviter toute fuite.
2. Isolation réseau #
Séparez les services selon leur niveau de confiance :
networks:
frontend:
# Services exposés (reverse proxy)
backend:
# Services internes uniquement
frontend, tous les autres services dans backend.
3. Mise à jour régulière #
# Automatisez les mises à jour avec un cron hebdomadaire
0 3 * * 0 cd /home/user/mediaserver-stack && docker compose pull && docker compose up -d
4. Restrictions d’accès #
- Activez l’authentification forte sur tous les services
- Utilisez un reverse proxy avec authentification (Authelia, Authentik)
- Limitez l’accès réseau avec un firewall (UFW, iptables)
Performance #
1. Optimisation du transcodage Navidrome #
environment:
- ND_TRANSCODINGCACHESIZE=2048MB # Augmentez selon RAM disponible
- ND_IMAGECACHESIZE=512MB
Le cache de transcodage évite de re-encoder les mêmes fichiers, économisant CPU et latence.
2. Indexation optimisée #
environment:
- ND_SCANSCHEDULE=1h # Scan fréquent si ajouts réguliers
# OU
- ND_SCANSCHEDULE=@daily # Scan quotidien si bibliothèque stable
Réduisez la fréquence de scan si votre bibliothèque change peu pour économiser des ressources.
3. Optimisation MariaDB #
Ajoutez des paramètres de performance pour MariaDB :
booklore-db:
command:
- --innodb-buffer-pool-size=256M
- --max-connections=50
4. Limitation des logs #
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Appliquez cette configuration à tous les services pour éviter la saturation du disque.
Haute disponibilité #
Pour un environnement de production critique, envisagez :
graph LR
LB["Reverse Proxy
Load Balancer"] --> N1["Navidrome
Instance 1"]
LB --> N2["Navidrome
Instance 2"]
N1 --> DB[("MariaDB
Master")]
N2 --> DB
DB -.Réplication.-> DBR[("MariaDB
Replica")]
style LB fill:#e1f5ff,stroke:#01579b,stroke-width:2px,color:#000
style N1 fill:#bbdefb,stroke:#1976d2,stroke-width:2px,color:#000
style N2 fill:#bbdefb,stroke:#1976d2,stroke-width:2px,color:#000
style DB fill:#b2dfdb,stroke:#00796b,stroke-width:2px,color:#000
style DBR fill:#b2dfdb,stroke:#00796b,stroke-width:2px,stroke-dasharray: 5 5,color:#000
Composants pour la HA :
- Load Balancer : HAProxy, Nginx, Traefik avec plusieurs backends Navidrome
- Réplication base de données : MariaDB Master-Slave ou Galera Cluster
- Stockage unifié : MergerFS avec SnapRAID pour protection des données (architecture Perfect Homelab)
Logs et observabilité #
Intégrez un système de monitoring centralisé :
# Exemple avec Loki pour l'agrégation de logs
services:
loki:
image: grafana/loki:latest
# Configuration Loki...
promtail:
image: grafana/promtail:latest
volumes:
- /var/lib/docker/containers:/var/lib/docker/containers:ro
# Configuration Promtail...
Stack d’observabilité recommandée :
- Prometheus : métriques système et applicatives
- Grafana : dashboards de visualisation
- Loki : agrégation et recherche de logs
- Promtail : collecteur de logs Docker
🎯 Conclusion #
Dans cet article, vous avez appris à :
- Déployer une infrastructure multimédia complète avec Docker Compose
- Exploiter l’architecture de stockage MergerFS + bind mounts LXC pour des performances optimales
- Configurer un conteneur LXC Proxmox optimisé avec transcodage matériel iGPU Intel
- Déployer Jellyfin pour le streaming vidéo avec accélération matérielle
- Utiliser Tiny Media Manager pour gérer les métadonnées de vos films et séries
- Installer Jellystat pour suivre les statistiques de visionnage Jellyfin
- Configurer Navidrome pour le streaming musical compatible Subsonic
- Déployer Music Assistant pour faciliter l’accès à la bibliothèque musicale via Home Assistant
- Mettre en place BookLore pour gérer vos livres numériques
- Implémenter un système d’analytics d’écoute auto-hébergé avec Maloja
- Synchroniser automatiquement vos écoutes avec Multi-Scrobbler
- Sécuriser et optimiser votre stack pour un usage quotidien
Cette stack est maintenant prête pour un usage personnel ou familial. Elle offre une alternative libre et respectueuse de la vie privée aux services de streaming propriétaires (Netflix, Spotify, Audible), tout en conservant le confort d’usage d’une plateforme moderne avec transcodage matériel et applications clients multiplateformes.
Pour aller plus loin #
Suggestions d’amélioration :
- Ajoutez un reverse proxy (Traefik, Caddy) avec HTTPS automatique via Let’s Encrypt
- Intégrez Music Assistant à Home Assistant pour créer des automatisations musicales (réveil en musique, ambiances, contrôle vocal) - Article à paraître dans la série Perfect Homelab
- Déployez Sonarr/Radarr/Lidarr pour automatiser la gestion de votre bibliothèque
- Configurez des sauvegardes automatiques vers un stockage distant (rclone, restic)
- Ajoutez Jellyseerr pour gérer les demandes de médias avec interface utilisateur moderne
- Configurez des sous-titres automatiques avec Bazarr
Ressources complémentaires #
- Jellyfin : Documentation officielle
- Tiny Media Manager : Documentation TMM
- Jellystat : Documentation GitHub
- Navidrome : Documentation officielle
- Maloja : Documentation GitHub
- BookLore : Documentation BookLore
- Music Assistant : Documentation Music Assistant
- Multi-Scrobbler : Guide de configuration