Général 8 min de lecture · 1 630 mots

Immich : remplacer Google Photos par ton propre serveur photo auto-hébergé

Immich : remplacer Google Photos par ton propre serveur photo auto-hébergé
Général · 2026.08.08

Le message de Google est arrivé début janvier : quota de stockage atteint à 94%, mise à niveau recommandée. 14,2 GB de photos sur 15 GB disponibles. J’aurais pu payer 3€/mois pour 100 GB et oublier le problème – sauf que j’ai déjà un NAS Synology DS414 avec plusieurs téraoctets libres et un homelab qui tourne H24 sur heighliner. Payer Google pour stocker des photos sur mes propres connexions internet, ça me semblait difficile à justifier.

Immich est devenu en deux ans la référence de l’auto-hébergement photo. Interface mobile iOS/Android quasi-identique à Google Photos, reconnaissance faciale, albums partagés, et une communauté active qui pousse des mises à jour régulières.

Contraintes et choix d’architecture

La VM cible est la VM 203 sur heighliner : Ubuntu 24.04 LTS, 4 vCPU, 6 GB RAM, VLAN 30 (réseau serveurs). Le stockage des photos ne sera pas sur le disque de la VM – il ira directement sur le NAS Synology DS414 via NFS, sur le VLAN 40 (stockage).

Pourquoi NFS plutôt que monter un volume supplémentaire sur la VM ? Le NAS est déjà le point de stockage central du homelab. Les photos dans Immich doivent co-exister avec les sauvegardes Proxmox Backup Server et les fichiers partagés. Avoir tout au même endroit simplifie la stratégie de sauvegarde.

La machine learning (reconnaissance faciale, classification de scènes) tournera en CPU-only. L’i9-13900H a 14 cœurs – c’est lent comparé à un GPU, mais fonctionnel pour un homelab où l’indexation n’est pas temps réel.

Préparer le NAS et le montage NFS

Sur le Synology DS414, créer le dossier partagé immich et activer le service NFS. Dans Panneau de configuration > Services de fichiers > NFS, s’assurer que NFS v4.1 est activé.

Ajouter une règle NFS pour la VM 203 (10.10.30.203) :

  • Privilèges : Lecture/Écriture
  • Squash : Pas de mapping
  • Sécurité : sys
  • Activer la connexion asynchrone

Côté VM 203 :

apt update && apt install -y nfs-common

# Créer le point de montage
mkdir -p /mnt/nas/immich

# Tester le montage manuel
mount -t nfs 10.10.40.10:/volume1/immich /mnt/nas/immich
df -h /mnt/nas/immich
# /dev/...  3.4T  890G  2.5T  27% /mnt/nas/immich

# Rendre le montage permanent
echo "10.10.40.10:/volume1/immich /mnt/nas/immich nfs defaults,_netdev,nfsvers=4.1 0 0" >> /etc/fstab

L’option _netdev est critique dans /etc/fstab pour un montage NFS. Sans elle, le système tente de monter le partage avant que le réseau soit disponible au démarrage, ce qui peut bloquer le boot de la VM.

Déployer Immich avec Docker Compose

Installer Docker :

curl -fsSL https://get.docker.com | sh
usermod -aG docker $USER

Télécharger la configuration officielle Immich :

mkdir -p /opt/immich
cd /opt/immich
wget -q https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
wget -q https://github.com/immich-app/immich/releases/latest/download/example.env -O .env

Éditer le fichier .env :

# /opt/immich/.env
UPLOAD_LOCATION=/mnt/nas/immich
EXTERNAL_PATH=/mnt/nas/immich
DB_PASSWORD=changeme_strong_password_here
IMMICH_VERSION=v1.111.0

Épingle toujours la version Immich dans .env (IMMICH_VERSION=v1.111.0). Le projet pousse des mises à jour fréquentes et certaines incluent des migrations de base de données – mieux vaut contrôler quand ça s’applique.

Démarrer la stack :

cd /opt/immich
docker compose up -d
docker compose logs -f --tail=50

Premier démarrage : attendre que le conteneur immich-server affiche Immich Server is listening on 0.0.0.0:3001. Les migrations de base de données initiales prennent environ 90 secondes.

Interface accessible sur http://10.10.30.203:2283. Créer le compte administrateur lors du premier accès – l’interface ne sera pas publiquement accessible avant la configuration de Traefik.

Accès externe via Traefik

J’utilise Traefik comme reverse proxy (déployé sur une autre VM du VLAN 30). La configuration pour Immich :

# Dans la config Traefik, ajouter un router et service
http:
  routers:
    immich:
      rule: "Host(photos.heighliner.arewel.com)"
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt
      service: immich

  services:
    immich:
      loadBalancer:
        servers:
          - url: "http://10.10.30.203:2283"

Let’s Encrypt émettra le certificat automatiquement au premier accès. Le domaine photos.heighliner.arewel.com est résolu en interne (DNS Pi-hole) et externalement (DNS public pointant vers l’IP du routeur avec port forwarding 443).

Migrer depuis Google Photos

Google Takeout exporte les photos par tranches de 10 GB maximum. Pour 38 GB, j’ai eu 4 archives ZIP.

# Sur la machine locale (pas la VM), télécharger les archives Takeout
# puis les copier sur la VM
rsync -avz --progress ~/Downloads/Takeout/ ubuntu@10.10.30.203:/tmp/takeout/

# Sur la VM, extraire tout
cd /tmp/takeout
for f in *.zip; do unzip -q "$f" -d extracted/; done

# Vérifier la structure
ls extracted/Takeout/Google Photos/
# Albums/  Photos from 2018/  Photos from 2019/  ...

L’export Google Photos contient les photos ET des fichiers JSON avec les métadonnées (date, géolocalisation, description). Si tu n’importes que les photos sans les JSON, Immich utilisera les dates EXIF embarquées dans les fichiers – ça marche pour la plupart des photos, mais les photos importées depuis des appareils tiers ou modifiées dans Google Photos peuvent perdre leur date d’origine.

Installer immich-cli pour l’upload :

# Sur la VM
npm install -g @immich/cli
immich login http://localhost:2283 ton@email.com
# Entrer le mot de passe quand demandé
# Un token est stocké dans ~/.config/immich/auth.yml

Upload avec préservation des métadonnées Google :

immich upload 
  --recursive 
  --delete 
  /tmp/takeout/extracted/Takeout/Google Photos/

Le flag --delete supprime les fichiers source après upload réussi – utile pour économiser de l’espace, mais à n’activer qu’une fois que tu es sûr que ça fonctionne.

L’upload de 38 GB a pris environ 3 heures sur le réseau local. La progression est affichée dans le terminal :

Found 8,342 assets, 234 albums
Uploading 8,342 assets...
[████████████████████] 8342/8342 (100%) | 38.2 GB uploaded
Created 234 albums

Reconnaissance faciale et indexation ML

Immich lance automatiquement les tâches d’indexation ML après l’upload. Sur l’interface d’administration (Administration > Jobs), tu peux voir l’avancement de chaque tâche.

Sur l’i9-13900H avec le conteneur immich-machine-learning en CPU-only :

  • Smart Search (CLIP) : environ 30 secondes pour 100 photos
  • Face Detection : environ 45 secondes pour 100 photos
  • 8 342 photos au total : indexation complète en un peu moins de 24 heures

Ce n’est pas rapide, mais c’est une opération one-shot. Après l’indexation initiale, les nouvelles photos sont indexées au fur et à mesure de l’upload, et ça prend quelques secondes par photo.

La reconnaissance faciale fonctionne correctement : Immich a automatiquement regroupé les visages et m’a demandé d’associer un nom à chaque groupe. Après avoir nommé une vingtaine de personnes, il reconnaît les nouvelles photos correctement dans environ 85% des cas – comparable à ce que faisait Google Photos sur le même corpus.

Application mobile et upload automatique

L’application Immich (iOS et Android) se configure avec l’URL externe https://photos.heighliner.arewel.com et les identifiants du compte.

Paramètres de backup automatique que j’ai configurés :

  • Backup déclenché sur WiFi uniquement (pas de backup sur 4G – la latence du domaine externe sur réseau mobile est trop élevée)
  • Inclure : Photos de la pellicule, Screenshots
  • Exclure : Fichiers temporaires des apps

La synchronisation sur le LAN (WiFi à la maison) est fluide. Parcourir 8 000 photos dans l’interface mobile est aussi réactif que Google Photos sur le même réseau. Sur 4G, c’est acceptable pour consulter des albums, mais pas idéal pour charger la timeline complète – la première requête prend 3-4 secondes contre moins d’une sur LAN.

Ce qui a coincé

Les Live Photos iOS ont posé problème. Une Live Photo est composée de deux fichiers : la photo HEIC et une vidéo MOV associée. Immich doit détecter cette association pour les afficher correctement (avec la petite animation au press).

Sur mes 8 342 fichiers, environ 400 Live Photos n’ont pas été correctement liées lors de l’import – elles apparaissaient comme une photo et une vidéo distinctes plutôt que comme une seule entrée.

C’est un bug connu dans Immich (plusieurs issues GitHub ouvertes). Le workaround documenté par la communauté : importer par lots de 500 fichiers maximum plutôt qu’en un seul --recursive. Le mécanisme de détection des paires HEIC/MOV semble mieux fonctionner sur des lots petits.

J’ai re-importé les Live Photos manuellement en lots :

# Lister les dossiers Google Photos contenant des Live Photos
# (identifiables par la présence de fichiers .mov à côté des .heic)
find /tmp/takeout/extracted -name "*.HEIC" -exec dirname {} ; | sort -u | while read dir; do
  if ls "$dir"/*.MOV 2>/dev/null | head -1 | grep -q .; then
    echo "$dir"
  fi
done > /tmp/live_photo_dirs.txt

# Re-importer par petits lots
while IFS= read -r dir; do
  immich upload "$dir"
done < /tmp/live_photo_dirs.txt

Après ce second passage, toutes les Live Photos étaient correctement liées.

Résultat

38 GB importés, 8 342 photos et vidéos, 234 albums restaurés depuis Google Photos. L'indexation ML complète (smart search + reconnaissance faciale) a terminé le lendemain matin.

Le quota Google Photos est redescendu à 2,1 GB - uniquement des documents Drive et des emails avec pièces jointes. Zéro euro dépensé en abonnement Google One depuis.

Le stockage NAS est vérifiable directement :

du -sh /mnt/nas/immich/
# 39G  /mnt/nas/immich/

Le NAS a encore plusieurs téraoctets libres. Les photos de la famille vont continuer à s'accumuler pendant des années sans qu'il faille gérer de quota.

Une remarque, un retour ?

Cet article est vivant - corrections, contre-arguments et retours de production sont les bienvenus. Trois canaux, choisissez celui qui vous convient.

Laisser un commentaire