Guide de déploiement

Dimensionner un VPS pour Jellyfin, Navidrome et Immich

Déployer sur un VPS Cloud →

Tutoriel

Dimensionner un VPS pour Jellyfin, Navidrome et Immich

Self-hosting13 min de lecture9 étapes

Regrouper films, musique, photos et audiolivres sur un seul serveur paraît simple, jusqu'au jour où Immich indexe vos visages et que la mémoire s'effondre. Une erreur de dimensionnement coûte dans les deux sens : un plan trop juste qui redémarre en boucle, ou un plan trop large payé chaque mois. Ce guide chiffre chaque service, fixe la règle qui évite le transcodage vidéo, budgète le disque par bibliothèque et assemble le tout derrière un seul reverse proxy. Il se termine par un tableau qui relie votre profil de bibliothèque à un plan VPS.

Sommaire· Pourquoi une seule machine pour quatre médiathèques1/14
  1. 01Pourquoi une seule machine pour quatre médiathèques
  2. 02Ce que vous gagnez à tout regrouper
  3. 03Le budget mémoire et processeur, service par service
  4. 04Budget de réservation par service
  5. 05Le budget disque : calculez en Go avant de choisir
  6. 06Ne pas transcoder : la règle qui protège le petit VPS
  7. 07Assembler la pile : un réseau, un proxy, un sous-domaine par service
  8. 08Sauvegarder chaque service, restaurer avant d'en avoir besoin
  9. 09Plan de sauvegarde par service
  10. 10Dépannage : mémoire saturée, droits refusés, envois coupés
  11. 11Les erreurs rencontrées et leur remède
  12. 12Quel plan pour quelle médiathèque
  13. 13Mesurer avant de payer plus
  14. 14La documentation officielle et la suite

Pourquoi une seule machine pour quatre médiathèques

Sortir de Plex, de Google Photos, de Spotify ou d'Audible conduit presque toujours à un service par type de média. Un VPS unique ramène quatre mises à jour, quatre certificats et quatre sauvegardes à un point d'entrée, un réseau Docker et un plan de sauvegarde.

La difficulté n'est pas l'installation, que nos guides sur Immich, Jellyfin, Navidrome et Audiobookshelf détaillent déjà. La difficulté est le dimensionnement : Immich et le transcodage vidéo écrasent un petit serveur, alors que Navidrome et Audiobookshelf passent presque inaperçus. Cet article répond à une seule question : quelle machine, pour quelle bibliothèque.

Ce que vous gagnez à tout regrouper

  • Un seul point d'entrée — un reverse proxy, un sous-domaine par service, des certificats obtenus et renouvelés automatiquement.
  • Une RAM mutualisée — Navidrome et Audiobookshelf consomment peu, la mémoire laissée libre par l'un profite aux pics de l'autre.
  • Un plan de sauvegarde unique — quatre dossiers de configuration, un dump PostgreSQL, un script.
  • Une montée en charge verticale — quand la bibliothèque grossit, vous augmentez RAM, vCPU et disque du même VPS sans réinstaller la pile.
  • Un accès root complet — vous choisissez la distribution, vous réglez le noyau, vous installez ce que la pile exige.

Le budget mémoire et processeur, service par service

Seuls les chiffres d'Immich et de Jellyfin viennent d'une documentation officielle ; les autres lignes sont des réglages de départ, à mesurer chez vous. Relevez vos valeurs une fois la pile en marche avec docker stats --no-stream, puis ajustez.

Immich est le poste dominant. Sa documentation donne 6 Go de RAM au minimum et 8 Go recommandés, 2 cœurs au minimum et 4 recommandés. Sur une machine à 4 Go, Immich tourne avec l'apprentissage automatique désactivé, et PostgreSQL demande au moins 2 Go si vous posez des limites Docker. Depuis la version 3, l'image d'apprentissage automatique sur amd64 exige le niveau de jeu d'instructions x86-64-v2 : vérifiez que le plan choisi l'expose.

Côté processeur, c'est l'indexation initiale qui sature, le temps de traiter la photothèque. Les autres services restent quasi invisibles tant que vous ne transcodez pas.

Budget de réservation par service

Faites défiler le tableau

ServiceRAM à réserverCe qui la fait grimper
Caddy (reverse proxy)Réglage de départ : 100 Mo, à mesurerPresque rien : le nombre de sous-domaines n'y change quasiment rien
NavidromeRéglage de départ : 250 Mo, à mesurerLes scans d'une grande bibliothèque et les clients qui demandent un transcodage audio
AudiobookshelfRéglage de départ : 250 Mo, à mesurerLes podcasts téléchargés automatiquement et les scans de métadonnées
Jellyfin en lecture directeRéglage de départ : 1 Go, à mesurer (Jellyfin : 4 Go possibles sans interface, 8 Go recommandés)Les analyses de bibliothèque et les images générées au premier passage
Jellyfin avec transcodage logicielAucun chiffre officiel par flux : à mesurer avec un flux d'essaiChaque flux converti en parallèle, surtout en HEVC ou avec incrustation de sous-titres
Immich (serveur, ML, PostgreSQL, Valkey)6 Go minimum, 8 Go recommandésL'indexation initiale, la reconnaissance faciale, la recherche sémantique
Pile complète, une seule machine8 Go au moins (valeur recommandée d'Immich), 16 Go pour la marge : une estimation à vérifierLes travaux Immich lancés pendant qu'un film est transcodé

Le budget disque : calculez en Go avant de choisir

Le disque est le premier plafond d'un VPS multimédia, et il se calcule. Pour la vidéo, la formule est : débit en Mb/s multiplié par la durée en secondes, divisé par 8. Un film de deux heures à 8 Mb/s pèse environ 7 Go, à 4 Mb/s environ 3,6 Go. Pour la musique, un album de 45 minutes en MP3 à 320 kb/s fait environ 110 Mo ; en FLAC, comptez plutôt 300 à 500 Mo. Un audiolivre de 10 heures à 64 kb/s pèse près de 290 Mo.

Pour les photos, partez de 3 Mo par cliché : 10 000 photos occupent donc environ 30 Go, vidéos de téléphone en sus. La documentation d'Immich ajoute que les miniatures et les vidéos transcodées augmentent la taille de la photothèque de 10 à 20 % en moyenne.

Séparez ensuite ce qui doit être rapide de ce qui doit être grand. La base PostgreSQL d'Immich pèse typiquement de 1 à 3 Go, doit vivre sur un SSD local et jamais sur un partage réseau. La configuration de Jellyfin et d'Audiobookshelf aussi : Audiobookshelf déconseille expressément de placer son dossier de configuration sur un partage réseau, au risque de corrompre sa base SQLite. Les médias, eux, peuvent aller sur un volume séparé et plus grand.

Ne pas transcoder : la règle qui protège le petit VPS

Jellyfin distingue quatre modes de lecture, du plus léger au plus lourd : lecture directe, remux, flux direct et transcodage. Sa documentation décrit la lecture directe comme une livraison du fichier sans modification, avec presque aucune charge supplémentaire pour le serveur ; le transcodage vidéo est le mode le plus coûteux.

Sans carte graphique, tout transcodage vidéo passe par le processeur, et la documentation de Jellyfin rappelle qu'un GPU est toujours recommandé pour cela. Elle prévient aussi que le HEVC, le VP9 et l'AV1 peuvent être très exigeants en logiciel, tout comme le tone-mapping HDR vers SDR faute de GPU.

La règle pratique tient en trois gestes. Stockez vos films dans un format que vos appareils lisent nativement, typiquement H.264 en MP4 ou MKV. Convertissez une fois, en amont, les fichiers problématiques plutôt que de les convertir à chaque lecture. Et utilisez le réglage par utilisateur de Jellyfin pour interdire le transcodage audio et vidéo aux comptes qui n'en ont pas besoin. Pour vérifier qu'un flux ne consomme rien, lancez une lecture : le tableau de bord affiche le type de lecture, et le processeur doit rester au repos.

Assembler la pile : un réseau, un proxy, un sous-domaine par service

  1. Créer les dossiers, les droits et le réseau partagé

    Séparez médias, photos et configurations, donnez la propriété à l'utilisateur 1000 et créez le réseau que partageront tous les conteneurs :

    sudo mkdir -p /srv/media/video /srv/media/music /srv/media/audiobooks /srv/photos /srv/stack/media /srv/stack/immich
    sudo mkdir -p /srv/stack/jellyfin/config /srv/stack/jellyfin/cache /srv/stack/navidrome/data /srv/stack/audiobookshelf/config /srv/stack/audiobookshelf/metadata
    sudo chown -R 1000:1000 /srv/stack /srv/photos
    sudo chmod -R a+rX /srv/media
    docker network create edge

  2. Pointer quatre sous-domaines vers le VPS

    Créez quatre enregistrements A (jellyfin, music, books, photos) vers l'IPv4 du VPS. Caddy obtient les certificats seulement si les enregistrements A ou AAAA pointent vers le serveur et si les ports 80 et 443 sont ouverts de l'extérieur.

  3. Écrire le compose des trois services légers

    Dans /srv/stack/media/compose.yaml, déclarez Jellyfin, Navidrome et Audiobookshelf. Aucun port n'est publié : seul Caddy parle au réseau edge. Les médias sont montés en lecture seule pour Jellyfin et Navidrome.

    services:
    jellyfin:
    image: jellyfin/jellyfin
    user: 1000:1000
    volumes:
    - /srv/stack/jellyfin/config:/config
    - /srv/stack/jellyfin/cache:/cache
    - /srv/media/video:/media:ro
    restart: unless-stopped
    networks: [edge]
    navidrome:
    image: navidrome/navidrome:latest
    user: 1000:1000
    volumes:
    - /srv/stack/navidrome/data:/data
    - /srv/media/music:/music:ro
    restart: unless-stopped
    networks: [edge]
    audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:latest
    user: 1000:1000
    volumes:
    - /srv/stack/audiobookshelf/config:/config
    - /srv/stack/audiobookshelf/metadata:/metadata
    - /srv/media/audiobooks:/audiobooks
    restart: unless-stopped
    networks: [edge]

  4. Ajouter Caddy au même fichier

    Complétez le fichier avec le service du proxy, puis les déclarations du réseau externe et du volume des certificats :

    caddy:
    image: caddy:2
    ports:
    - "80:80"
    - "443:443"
    volumes:
    - ./Caddyfile:/etc/caddy/Caddyfile:ro
    - caddy_data:/data
    restart: unless-stopped
    networks: [edge]
    networks:
    edge:
    external: true
    volumes:
    caddy_data:

  5. Écrire le Caddyfile, un bloc par service

    Dans /srv/stack/media/Caddyfile, un nom de domaine suffit à déclencher le TLS automatique, et Caddy redirige HTTP vers HTTPS tout seul :

    jellyfin.votre-domaine.com {
    reverse_proxy jellyfin:8096
    }
    music.votre-domaine.com {
    reverse_proxy navidrome:4533
    }
    books.votre-domaine.com {
    reverse_proxy audiobookshelf:80
    }
    photos.votre-domaine.com {
    reverse_proxy immich_server:2283
    }

  6. Installer Immich avec son compose officiel

    Téléchargez les deux fichiers de la dernière version, et ne modifiez pas le compose lui-même :

    cd /srv/stack/immich
    wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
    wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

    Dans .env, réglez les trois valeurs ci-dessous (le mot de passe n'accepte que des lettres et des chiffres) :

    UPLOAD_LOCATION=/srv/photos/library
    DB_DATA_LOCATION=/srv/stack/immich/postgres
    DB_PASSWORD=<mot-de-passe-A-Za-z0-9>

  7. Brancher Immich sur le réseau commun

    Créez /srv/stack/immich/docker-compose.override.yml. Docker Compose le fusionne automatiquement avec le fichier officiel, qui reste intact et remplaçable à chaque mise à jour :

    services:
    immich-server:
    networks: [default, edge]
    networks:
    edge:
    external: true

  8. Démarrer et vérifier chaque entrée

    Lancez les deux piles, attendez l'émission des certificats, puis testez en-têtes HTTP et TLS. Vous devez obtenir un code 2xx ou 3xx sur HTTPS, jamais une erreur de certificat :

    cd /srv/stack/media && docker compose up -d
    cd /srv/stack/immich && docker compose up -d

    curl -I https://jellyfin.votre-domaine.com
    curl -I https://photos.votre-domaine.com

  9. Mesurer, puis régler Immich

    Pendant l'indexation, relevez docker stats --no-stream et la charge du processeur. Si la mémoire frôle le plafond, désactivez une fonction d'apprentissage automatique (recherche intelligente, reconnaissance faciale) dans les réglages d'administration, ou baissez la concurrence des tâches sans la porter au-delà du nombre de cœurs.

Sauvegarder chaque service, restaurer avant d'en avoir besoin

Le piège classique est de sauvegarder les photos sans la base : Immich ne scanne pas son dossier de bibliothèque, il se fie à sa base pour savoir ce qui existe. La documentation distingue les dossiers originaux (library, upload, profile), à sauvegarder impérativement, des dossiers régénérables (thumbs, encoded-video).

Immich produit aussi ses propres dumps de base, par défaut chaque jour à 2 h du matin, avec les 14 derniers conservés dans le dossier backups de l'emplacement de téléversement. Ils ne contiennent que des métadonnées, jamais les photos. Pour garantir la cohérence, arrêtez le conteneur du serveur pendant la sauvegarde ; sinon, sauvegardez la base d'abord, puis les fichiers.

Restauration, sur une machine de test, selon la procédure officielle (puis injection du dump dans psql). Attention : down -v efface toutes les données Immich de la machine où vous l'exécutez :

docker compose down -v
docker compose pull
docker compose create
docker start immich_postgres

Plan de sauvegarde par service

  • Immich, base — un dump compressé hors du VPS : docker exec -t immich_postgres pg_dump --clean --if-exists --dbname=immich --username=postgres | gzip > "/srv/backup/immich-db.sql.gz", en adaptant nom de base et utilisateur à votre .env.
  • Immich, fichiers — library, upload et profile copiés avec rsync vers un stockage distant ; thumbs et encoded-video peuvent être régénérés.
  • Jellyfin — le dossier /srv/stack/jellyfin/config (bibliothèques, utilisateurs, métadonnées), conteneur arrêté le temps de l'archive. Le cache se reconstruit.
  • Navidrome — /srv/stack/navidrome/data (base, listes de lecture, cache) ; la musique elle-même est votre source de vérité et se sauvegarde comme un dossier de fichiers.
  • Audiobookshelf — /config et /metadata : la base SQLite et la progression d'écoute vivent dans le premier, les sauvegardes internes dans le second.
  • La restauration se teste — rejouez la procédure officielle d'Immich, détaillée au-dessus, sur une machine de test avant de vous y fier.

Dépannage : mémoire saturée, droits refusés, envois coupés

Les pannes de cette pile tiennent en deux familles : la mémoire, quand Immich et un transcodage se disputent les mêmes gigaoctets, et les droits, quand un conteneur non root ne peut pas lire ou écrire un dossier monté. Pour la première, commencez par chercher une trace du noyau avec dmesg -T | grep -i "out of memory" : si un processus Immich y figure, le noyau l'a tué faute de mémoire, et le conteneur repart en boucle. Pour la seconde, comparez toujours l'identifiant de l'utilisateur du conteneur au propriétaire des dossiers montés.

Les erreurs rencontrées et leur remède

  • Immich redémarre en boucle sur un petit plan — le noyau tue le conteneur d'apprentissage automatique (cherchez out of memory dans dmesg). Désactivez la recherche intelligente et la reconnaissance faciale, ou passez à un plan avec au moins 8 Go.
  • can't set healthcheck.start_interval as feature require Docker Engine v25 or later — votre Docker est trop ancien. Mettez-le à jour, ou commentez la ligne start_interval dans la section database du compose, comme l'indique la documentation d'Immich.
  • Téléversements de vidéos coupés après une minute — la documentation d'Immich relève un code 499 derrière Traefik avec le délai de lecture par défaut de 60 secondes, et recommande 600 secondes. Vérifiez le délai de votre proxy.
  • Navidrome : unable to open database file — le dossier /data n'est pas accessible en écriture. Donnez-en la propriété à l'identifiant défini par la directive user.
  • Navidrome démarre mais la bibliothèque reste vide, avec permission denied dans les journaux — le dossier de musique n'est pas lisible : appliquez chmod -R a+rX sur /srv/media/music.
  • Jellyfin ne voit pas les films — l'utilisateur 1000 du conteneur ne peut pas lire le dossier monté. Testez avec docker exec jellyfin ls /media et corrigez les droits ; PUID et PGID ne fonctionnent pas avec ces images, seule la directive user compte.

Quel plan pour quelle médiathèque

Faites défiler le tableau

Profil de bibliothèquePlan conseilléMarge et limite
Musique, audiolivres et quelques films en lecture directe, Immich sans apprentissage automatique, un ou deux utilisateursVPS Start : 2 vCPU, 4 GB, 50 GB SSD, à 99 DH/moisMémoire juste : Immich reste sans ML et le transcodage est à éviter ; le disque limite à quelques films (≈ 7 Go pour un film de deux heures à 8 Mb/s)
Photothèque familiale d'environ 10 000 clichés (30 à 36 Go) avec ML actif, musique et audiolivres, lecture directeVPS Power : 4 vCPU, 8 GB, 100 GB SSD, à 299 DH/moisAtteint les 8 Go recommandés pour Immich seul ; l'indexation initiale ralentit le reste
Pile complète à quatre services, deux ou trois utilisateurs, un transcodage ponctuelVPS Business : 8 vCPU, 16 GB, 200 GB SSD, à 499 DH/moisConfortable ; le disque devient le plafond dès que la vidéo dépasse quelques centaines de Go
Plusieurs flux transcodés en même tempsVPS Business au minimum, et la conversion en amont des fichiersSans GPU, ajouter des vCPU ne suffit pas : mieux vaut convertir une fois que transcoder à chaque lecture

Mesurer avant de payer plus

Commencez par le plan que le tableau indique, lancez l'indexation d'Immich et relevez la mémoire avec docker stats --no-stream pendant une journée de pointe. Si la marge dépasse 30 %, vous avez la bonne taille ; si le noyau tue un conteneur, montez le plan. La scalabilité verticale du VPS évite la réinstallation : RAM et disque augmentent, vos dossiers /srv et vos composes restent en place.

La documentation officielle et la suite

Les valeurs de ce guide viennent de la documentation des éditeurs : prérequis d'Immich, sauvegarde et restauration d'Immich, choix du matériel pour Jellyfin, transcodage Jellyfin, Navidrome avec Docker et le HTTPS automatique de Caddy.

Pour choisir un autre proxy que Caddy, lisez notre comparatif Caddy, Traefik et Nginx Proxy Manager. Si vous quittez Plex, la démarche est détaillée dans notre guide de migration vers Jellyfin et Navidrome.

Un VPS qui grandit avec votre médiathèque

Avec un VPS ServOrbit.com, vous avez l'accès root, l'IPv4 dédiée, le SSD NVMe et le choix de la distribution. Quand la bibliothèque grossit, la scalabilité verticale ajoute RAM et disque sans réinstaller. L'option administration VPS est disponible.

Besoin d'aide ?

Parcourez notre centre d'aide et notre FAQ, ou contactez notre équipe — rappel, WhatsApp ou e-mail. Support en français, anglais et arabe.

Écrire sur WhatsApps'ouvre dans un nouvel onglet