Introduction — Le problème des 60 Mpx

Un fichier RAW Sony a7r IV ≈ 120 Mo. Une sortie photo typique : 50–200 vues → 2 à 5 Go de RAW + 500 Mo–1 Go d’exports (DNG masters, versions web, réseaux sociaux).

Mon objectif : zéro friction entre la prise de vue, le développement, la sauvegarde et la publication. Pas de copie manuelle, pas de « où est ce fichier ? », pas de disque plein au mauvais moment.


Architecture globale — Vue d’ensemble

Schema technique

Légende :
🟢 Local (SSD NVMe) — 🔵 Stockage maître (NAS ZFS) — 🟠 Diffusion (Cloudinary CDN) — 🩷 Sauvegarde hors site (pCloud crypté) — 🟣 Recherche (Immich)


Étape 1 — Ingestion & tri local (Lightroom)

  1. Import direct sur SSD NVMe local (vitesse maximale, pas de latence réseau)
  2. Présélection + rejets avant toute copie vers le NAS — on ne sauvegarde que ce qui vaut le coup
  3. Nommage normalisé : YYYYMMDD_Collection_XXXX.ARW
    Exemple : 20260315_Murmurs_0042.ARW
  4. Métadonnées IPTC à l’import (via préréglage Lightroom) :
    • Copyright : © Frédéric Le Monnier
    • Localisation (GPS si dispo, sinon ville/région)
    • Mots-clés hiérarchiques : Paysage > Forêt, Technique > Longue exposition, etc.

💡 Astuce : un préréglage d’import « Portfolio » applique nommage + IPTC + mots-clés de base en 1 clic.


Étape 2 — Développement & exports (Photoshop)

Lien direct avec ma Recette Photoshop #1 (correction teinte dominante) et les futures recettes.

Depuis le master développé (PSD/TIFF 16 bits), trois exports automatisés via une action Photoshop « Export Trio » :

Usage Format Dimension max Compression Destination
Archive master TIFF 16-bit / PSD 9504 × 6336 (plein 60 Mpx) Sans perte (ZIP) 01_DEVELOPPEES/
Portfolio web AVIF / WebP 2400 px (grand côté) q_auto:eco 02_EXPORTS_WEB/
Réseaux sociaux JPEG 1600 px (grand côté) q=80 03_EXPORTS_SOCIAL/

Action Photoshop « Export Trio » (1 raccourci clavier) :

  1. Duplique le master → convertit en 8 bits sRGB
  2. Redimensionne + sharpen sortie (bicubique, 0.3 px)
  3. Enregistre les 3 versions dans les bons dossiers NAS (via chemin SMB monté)
  4. Écrit métadonnées EXIF/IPTC propres (sans historique Photoshop)

Étape 3 — NAS : stockage maître + accès réseau

Matériel (détails dans Pourquoi un NAS ?) :

  • TrueNAS Scale (ZFS natif)
  • AMD Ryzen 7 + 64 Go DDR5 ECC
  • 7 × Seagate IronWolf 4 To → RAID-Z2 ≈ 10 To utiles, tolérance 2 pannes

Structure de dossiers (montée en lecteur réseau Z: / /Volumes/Photos) :

/mnt/pool/photos/
├── 00_RAW_MASTERS/           # RAW originaux (readonly après import validé)
│   └── 2026/03_Murmurs/
├── 01_DEVELOPPEES/           # TIFF/PSD masters développés
│   └── 2026/03_Murmurs/
├── 02_EXPORTS_WEB/           # AVIF/WebP pour Cloudinary
│   └── 2026/03_Murmurs/
└── 03_EXPORTS_SOCIAL/        # JPEG pour IG/Bluesky
    └── 2026/03_Murmurs/

Protections ZFS :

  • Snapshots quotidiens (conservés 30 j) → récupération fichier supprimé/modifié en 1 clic
  • Scrub mensuel (1er du mois, 03:00) → détection/correction erreurs silencieuses
  • Réplication locale : 2e pool USB pour copie froide mensuelle (disque hors tension)

Étape 4 — Sauvegarde hors site : pCloud (chiffré côté client)

TrueNAS → pCloud via rclone + crypt (cron nightly 02:00) :

# /root/scripts/rclone_crypt_sync.sh
rclone sync /mnt/pool/photos/ pcloud_crypt:photos \
  --transfers 4 --checkers 8 --bwlimit 20M \
  --log-file /var/log/rclone_pcloud.log \
  --progress
  • Chiffrement client : rclone config → pcloud_crypt (crypt sur pcloud:) → pCloud ne voit que des noms de fichiers illisibles + données chiffrées
  • Rétention : versioning 90 j + corbeille 1 an (config pCloud)
  • Coût : ~180 € « 2 To lifetime » (promo) → 0 €/an récurrent

⚠️ Test de restauration annuel : je récupère un RAW 2023 depuis pCloud → vérifie intégrité (hash SHA256) → OK.


Étape 5 — Cloudinary : CDN & transformations à la volée

Upload automatique : script Python watchdog surveille 02_EXPORTS_WEB/ → upload API Cloudinary à la détection de nouveau fichier.

Presets Cloudinary (configurés dans le dashboard) :

Preset Transformation Usage
portfolio_large w_2400,f_auto,q_auto:eco Image principale article/lightbox
portfolio_thumb w_600,c_fill,g_auto,f_auto,q_auto Grilles, vignettes, recherche
og_image w_1200,h_630,c_fill,g_auto,f_auto Open Graph / Twitter Card

Intégration Jekyll : chaque photo de collection a un cloudinary_id en front-matter → tag Liquid personnalisé :

{ % cloudinary portfolio_large { { page.cloudinary_id } } alt:"{ { page.title } }" % }

Génère automatiquement :

  • <picture> avec source type="image/avif", source type="image/webp", fallback <img>
  • srcset responsive (400w, 800w, 1200w, 2400w)
  • loading="lazy" + decoding="async"

URL signées (expiration 1 an) → maîtrise du cache + protection hotlink.


Étape 6 — Indexation & recherche : Immich (self-hosted)

Docker Compose sur TrueNAS (même machine, réseau isolé) :

# docker-compose.immich.yml
services:
  immich-server:
    image: ghcr.io/immich-app/immich-server:latest
    volumes:
      - /mnt/pool/photos/01_DEVELOPPEES:/usr/src/app/upload:ro
    environment:
      - DB_HOST=postgres
      - REDIS_HOST=redis
  postgres: ...
  redis: ...

Fonctionnalités utilisées :

  • Recherche texte (mots-clés IPTC lus depuis les TIFF)
  • Géolocalisation (carte interactive)
  • Similarité visuelle (« trouve-moi les photos qui ressemblent à celle-ci »)
  • Albums partagés (lien privé, sans exposer les RAW ni le NAS)

Coûts & bilan — Vrai budget 2026

Poste Coût initial Coût annuel Durée de vie estimée
TrueNAS DIY (CPU/RAM/6 HDD) ~1 200 € 0 € 5–7 ans
pCloud 2 To lifetime (promo) ~180 € 0 € « à vie »
Cloudinary (gratuit 25 Go) 0 € 0 € —
Électricité NAS (15 W en moyenne) — ~60 € —
Total ~1 380 € ~60 €/an < 0,15 €/Go/an

Comparatif : Adobe Creative Cloud 1 To = 120 €/an, Google Photos 2 To = 100 €/an — sans contrôle, sans RAW, sans indexation locale.


Automatisation — Scripts clés (extraits)

Tous versionnés dans mon repo privé GitHub photo-workflow (facile à cloner sur nouvelle machine).

ingest.sh — SD → Local → Lightroom → NAS

#!/bin/bash
set -euo pipefail
SRC="/media/fred/SD_CARD/DCIM"
DST_LOCAL="/home/fred/Photos/Ingest/$(date +%Y%m%d)_$1"
mkdir -p "$DST_LOCAL"
rsync -av --progress "$SRC"/ "$DST_LOCAL"/
# Lightroom importe via dossier surveillé (auto-import)
# Puis renommage + move vers NAS via script post-import LR

export_trio.jsx — Photoshop Action (JavaScript)

// Export Trio - raccourci F12
var doc = app.activeDocument;
var baseName = doc.name.replace(/\.[^\.]+$/, '');
var exportPath = "/Volumes/Photos/02_EXPORTS_WEB/2026/03_Murmurs/";

// 1. Archive TIFF 16-bit
saveTIFF(doc, "/Volumes/Photos/01_DEVELOPPEES/2026/03_Murmurs/" + baseName + ".tif");

// 2. Web AVIF 2400px
resizeExport(doc, 2400, exportPath + baseName + ".avif", "AVIF", 75);

// 3. Social JPEG 1600px
resizeExport(doc, 1600, "/Volumes/Photos/03_EXPORTS_SOCIAL/2026/03_Murmurs/" + baseName + ".jpg", "JPEG", 80);

cloudinary_sync.py — Watchdog → Cloudinary

#!/usr/bin/env python3
import cloudinary.uploader
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import os, time

WATCH_DIR = "/mnt/pool/photos/02_EXPORTS_WEB"
CLOUDINARY_FOLDER = "portfolio/2026"

class Handler(FileSystemEventHandler):
    def on_created(self, event):
        if event.is_directory: return
        if not event.src_path.lower().endswith(('.avif', '.webp')): return
        time.sleep(2)  # attendre fin écriture
        public_id = os.path.relpath(event.src_path, WATCH_DIR).replace(os.sep, '/')
        cloudinary.uploader.upload(
            event.src_path,
            folder=CLOUDINARY_FOLDER,
            public_id=public_id,
            use_filename=True,
            unique_filename=False,
            tags=["portfolio", "2026"],
            eager=[{"transformation": "portfolio_large"}, {"transformation": "portfolio_thumb"}]
        )

observer = Observer()
observer.schedule(Handler(), WATCH_DIR, recursive=True)
observer.start()
try:
    while True: time.sleep(60)
except KeyboardInterrupt:
    observer.stop()
observer.join()

rclone_crypt_sync.sh — Cron 02:00

#!/bin/bash
# /etc/cron.d/nas-pcloud-sync
0 2 * * * root /root/scripts/rclone_crypt_sync.sh >> /var/log/rclone_pcloud_cron.log 2>&1

Principaux enseignements

📌 Séparer les responsabilités : stockage maître (NAS ZFS) ≠ diffusion web (Cloudinary CDN) ≠ sauvegarde hors site (pCloud crypté)
📌 Automatiser dès la 2e occurrence : un script > 100 clics manuels, et ça ne oublie jamais une étape
📌 Chiffrer côté client avant tout cloud : confiance zéro — le fournisseur ne voit que du bruit
📌 Tester la restauration 1×/an : un backup non testé n’est pas un backup
📌 Garder la main sur les métadonnées : IPTC dans le fichier = portable, lisible par n’importe quel outil (Immich, Lightroom, ExifTool, mon Jekyll)


Conclusion

Ce workflow me permet de :

  • Photographier sans me soucier de l’espace (16 To utiles, extensible)
  • Développer à vitesse locale (SSD NVMe)
  • Publier instantanément sur le web (Cloudinary CDN mondial)
  • Dormir tranquille (ZFS snapshots + pCloud crypté hors site)
  • Retrouver n’importe quelle image en secondes (Immich + IPTC)

Prochaine étape : intégration Lightroom Classic → NAS via Smart Previews (édition hors-ligne, sync ultérieure) — article dédié à venir.

Et vous, qu’en pensez-vous ? Racontez-nous votre expérience dans les commentaires juste en dessous !