Skip to content

Stockage Personnel — Rapport d'Avancement

Date : 2026-04-04
Référence : storage-02-implementation.md
Session : Déploiement autonome root@pve — agent GitHub Copilot


Résumé Exécutif

Les phases 1 (ZFS), 2 (rclone), 3 (LXC 106 + SFTPGo + nginx) et 7 (documentation) sont complètes. L'infrastructure est opérationnelle. Le flow OIDC a nécessité cinq correctifs non prévus dans le spec (détaillés en §2). https://files.ncls.ltd est accessible. Le web client (alice, nico) et l'interface admin (nico) fonctionnent via SSO Authelia OIDC avec implicit_roles. WebDAV activé (webdavd, port 8091, préfixe /dav) — montage lecteur réseau Windows/Mac disponible sur https://files.ncls.ltd/dav.

Phases restantes : Phase 4 (ZfDash) — exclu explicitement. Phases 5 (Takeout) et 6 (HGST) — non démarrées, dépendent d'actions manuelles.

Point d'attention : Alice a un mot de passe temporaire (e6lHH92W06c5pKrA) dans Authelia — à changer via https://auth.ncls.ltd.


1. État par Phase

Phase 1 — Conversion ZFS ✅ Complète

Élément Spécification État réel
Pool ZFS storage /dev/sdd, ashift=12, compression=zstd ✅ Identique
Dataset storage/alice Créé
Dataset storage/nico Créé (892 MB — archives OVH restaurées)
Dataset storage/family Créé
Dataset storage/shared Créé
Dataset storage/others Optionnel ❌ Non créé (hors scope)
Structure de répertoires {alice,nico}/{drive,photos,archives}, family/{drive,archives}
Archives restaurées Contenu /mnt/storage pré-ZFS → /mnt/storage/nico/archives/
Propriétaire /mnt/storage UID 1000 (storage user)
Sanoid daily×7 / weekly×4 / monthly×3 sur les 4 datasets sanoid.timer actif
Point de montage /mnt/storage

Écart : storage/others non créé — optionnel dans le spec, à créer si des guests doivent avoir une inbox dédiée.


Phase 2 — rclone PULL ✅ Complète

Élément Spécification État réel
Renommer remote gdrive:gdrive-nico:
Mettre à jour scripts backup backup-docker-configs.sh, backup-proxmox-host.sh
Remote gdrive-alice: Créer via rclone config (OAuth interactif) ✅ Configuré 2026-04-04
Script /usr/local/bin/pull-gdrive.sh Sync alice + nico + family
Cron /etc/cron.d/pull-gdrive 03h00 quotidien ✅ Actif
Sync nico/drive gdrive-nico:/ → /mnt/storage/nico/drive/ ✅ Premier run lancé 2026-04-04
Sync alice/drive gdrive-alice:/ → /mnt/storage/alice/drive/ ✅ Premier run lancé 2026-04-04
Sync family/drive gdrive-nico:famille/ (écart vs spec — voir §2)

Écart vs spec : le spec indiquait gdrive-alice:Dossier-Partage/ comme source du dossier famille. En réalité le dossier partagé est accessible depuis gdrive-nico:famille/. Le script est corrigé en conséquence.


Phase 3 — LXC 106 + SFTPGo ✅ Complète

LXC 106 ✅

Élément Spécification État réel
IP / hostname 192.168.1.106 / storage
Custom idmap UID 1000 lxc.idmap: u/g 0 100000 1000 + u/g 1000 1000 1 + u/g 1001 101001 64535
Bind mounts storage mp1: /mnt/storage
Écart — ZFS subdatasets Spec: un seul mp1 ⚠️ mp1 à mp5 nécessaires (voir ci-dessous)
Bind mount 106-storage mp0: /mnt/lxc-data/106-storage → /opt/docker
Nesting (Docker) features: nesting=1
Docker CE v29.3.1
Portainer agent Non fait — docker compose classique utilisé ℹ️ Par instruction utilisateur

Écart critique découvert : Les sous-datasets ZFS (storage/alice, storage/nico, etc.) ne se propagent pas dans un bind mount LXC via mp1: /mnt/storage. Chaque dataset doit avoir son propre mp :

# /etc/pve/lxc/106.conf — configuration réelle
mp0: /mnt/lxc-data/106-storage,mp=/opt/docker
mp1: /mnt/storage,mp=/mnt/storage
mp2: /mnt/storage/alice,mp=/mnt/storage/alice
mp3: /mnt/storage/nico,mp=/mnt/storage/nico
mp4: /mnt/storage/family,mp=/mnt/storage/family
mp5: /mnt/storage/shared,mp=/mnt/storage/shared

Correction à apporter dans le spec : Documenter ce comportement ZFS+LXC pour les futures installations.

Docker Compose SFTPGo ✅ avec écarts

Fichier : /mnt/lxc-data/106-storage/docker-compose.yml

Élément Spécification État réel
Image drakkan/sftpgo:v2.7.1
Port 2022 (SFTP)
Port 8090 (httpd — web UI + REST API)
Port 8091 (webdavd — WebDAV) Non prévu dans spec ✅ Ajouté 2026-04-04
Port 8080 (admin)
Volume /mnt/storage:/storage
Volume /mnt/media:/media:ro Optionnel (accès admin nico) ❌ Non monté (hors scope)
user: "1000:1000" Non mentionné dans spec ✅ Ajouté (nécessaire pour lecture des fichiers UID 1000)
extra_hosts: auth.ncls.ltd:192.168.1.103 Non mentionné dans spec ✅ Ajouté (correctif DNS — voir §2.3)
ENABLE_WEB_ADMIN=true sur binding 0 (port 8090) Spec: sur binding 1 / port 8080 uniquement ✅ Activé sur les deux bindings (nécessaire pour OIDC côté client)
IMPLICIT_ROLES=true (OIDC admin role) Non prévu dans spec ✅ Solution finale — SFTPGo détermine le rôle depuis sa propre BDD (voir §2.5)

Configuration SFTPGo ✅

Élément Spécification État réel
Virtual folder family /storage/family [rw]
Virtual folder snapshots /storage/.zfs/snapshot [ro]
Virtual folder shared /storage/shared [ro]
Virtual folder media /media [ro] — optionnel ❌ Non créé (volume non monté)
Groupe ownershome_dir /storage/%username%
Groupe owners-shared — virtual folders family [rw] + .snapshots [ro]
Groupe guests virtual folder shared [ro]
User alice — groupes primary=owners, secondary=owners-shared
User nico — groupes primary=owners, secondary=owners-shared
User nico — rôle admin OIDC Via IMPLICIT_ROLES=true (entité admin dans la BDD SFTPGo) ✅ (écart vs spec — voir §2.5)
Admin local SFTPGo Compte nico, mot de passe changé

Note : dans l'API SFTPGo v2.7.1, virtual_folders doit être placé au niveau racine du groupe (pas dans user_settings). Le champ user_settings.virtual_folders est silencieusement ignoré.

Authelia ✅ avec correctifs non prévus

Élément Spécification État réel
Client OIDC sftpgo
redirect_uri https://files.ncls.ltd/web/oidc/redirect
Scopes openid profile email ✅ (simplifié — implicit_roles ne nécessite plus le claim groups)
token_endpoint_auth_method: client_secret_post
claims_policy: sftpgo_policy Non prévu — requis Authelia 4.38+ ✅ Ajouté
preferred_username dans ID token Non prévu — requis Authelia 4.38+ ✅ Via claims_policies.sftpgo_policy
Compte alice Absent du rapport initial ✅ Ajouté — mot de passe temp e6lHH92W06c5pKrA ⚠️ à changer
Groupe sftpgo_admin pour nico Non prévu ✅ Conservé dans Authelia — inutile depuis passage à implicit_roles (voir §2.5)

nginx ✅

  • Vhost files.ncls.ltd : /mnt/lxc-data/103-network/nginx/conf.d/files.ncls.ltd.conf
  • Routage par chemin :
  • location /dav/http://192.168.1.106:8091 (webdavd — WebDAV Basic Auth)
  • location /http://192.168.1.106:8090 (httpd — web UI OIDC + REST API + tout le reste)
  • client_max_body_size 0 (uploads illimités)
  • Headers WebDAV (Destination, Authorization) passés
  • Config testée et rechargée ✅
  • Vhost sftpgo-admin.internal (port 8080, VPN only) : ❌ Non créé — admin accessible sur LAN direct uniquement à ce stade

Incident 2026-04-06 : après le --force-recreate de SFTPGo, le cache ARP de LXC 106 est devenu STALE, bloquant les réponses TCP sortantes → 504 sur tous les accès. Résolu par un ping -I eth0 depuis LXC 106 pour forcer le rafraîchissement ARP. Cause racine : renouvellement du cache ARP local incomplet après redémarrage du daemon Docker.


Phase 4 — ZfDash ❌ Exclu

Exclu explicitement par l'utilisateur pour cette session. Non implémenté, pas de changement sur LXC 101.

Phase 5 — Backup Photos (Takeout) ❌ Non démarré

Phase 6 — Migration Archives HGST ❌ Non démarrée (disque non branché)

Phase 7 — Documentation ✅ Complète

Page Action État
infrastructure/proxmox/containers/106-storage.md Créé
infrastructure/proxmox/containers/index.md LXC 106 ajouté
infrastructure/hardware/storage/hdd-storage.md Mis à jour ZFS + datasets
applications/sftpgo.md Créé
applications/index.md Section LXC 106 Storage ajoutée
maintenance/backup/offsite.md Remotes + pull-gdrive ajoutés
infrastructure/proxmox/index.md Cron pull-gdrive + remotes rclone ajoutés
roadmap/index.md ✅ Stockage personnel marqué réalisé
applications/zfdash.md Hors scope (Phase 4 exclue)

2. Correctifs Non Prévus dans le Spec

2.1 ZFS subdatasets non propagés dans bind mount LXC

Symptôme : Avec mp1: /mnt/storage,mp=/mnt/storage seul, les répertoires /mnt/storage/alice, nico, etc. apparaissaient comme nobody:nogroup (UID 65534) dans LXC 106.

Cause : Chaque dataset ZFS est un système de fichiers distinct. Un bind mount LXC ne propage pas les sous-montages automatiquement (contrairement à un bind mount Linux classique sur ext4).

Correctif : Ajouter mp2 à mp5 pour chaque dataset enfant explicitement.

2.2 SFTPGo config_url ne doit pas inclure le suffixe découverte

Symptôme : could not start HTTP server: oidc: unable to initialize provider for URL "…/.well-known/openid-configuration": 404 Not Found

Cause : SFTPGo ajoute automatiquement /.well-known/openid-configuration au config_url. La valeur correcte est l'URL de l'issuer seul.

Correctif :

# ❌ Incorrect (spec storage-02)
config_url: "https://auth.ncls.ltd/.well-known/openid-configuration"

# ✅ Correct
SFTPGO_HTTPD__BINDINGS__0__OIDC__CONFIG_URL=https://auth.ncls.ltd

2.3 DNS interne Docker ne résout pas auth.ncls.ltd lors du token exchange

Symptôme : Après authentification Authelia réussie, retour sur SFTPGo avec : failed to exchange oidc token: Post "https://auth.ncls.ltd/api/oidc/token": dial tcp: lookup auth.ncls.ltd on 127.0.0.11:53: server misbehaving

Cause : Le serveur DNS Docker interne (127.0.0.11) ne peut pas résoudre le domaine public auth.ncls.ltd à l'intérieur du réseau Docker de LXC 106. La discovery initiale fonctionnait (Go cache la réponse) mais l'échange de token échoue à chaud.

Correctif :

# docker-compose.yml
extra_hosts:
  - "auth.ncls.ltd:192.168.1.103"

2.4 preferred_username absent de l'ID token — Authelia 4.38+

Symptôme : username field "preferred_username" not found, empty or not a string, claims fields: [exp iat nonce amr auth_time azp iss jti sub at_hash aud]

Cause : À partir d'Authelia v4.38, les claims profile (preferred_username, name, email, etc.) ne sont plus inclus dans l'ID token par défaut. Ils doivent être déclarés explicitement via une claims_policy.

Correctif (dans configuration.yml) :

identity_providers:
  oidc:
    claims_policies:
      sftpgo_policy:
        id_token:
          - preferred_username
          - email
          - groups
    clients:
      - client_id: sftpgo
        claims_policy: sftpgo_policy
        # ... reste de la config

2.5 Rôle admin OIDC — Résolution en 5 correctifs cascade

Spécification : le spec ne documentait pas de mécanisme précis pour le rôle admin OIDC. La résolution a nécessité 5 correctifs successifs (2 sessions, ~4h cumulées).

Correctif 1 — ROLE_FIELD=groups incompatible avec le tableau Authelia

Symptôme : Incorrect OpenID role à la connexion admin OIDC.

Cause : ROLE_FIELD=groups attend une chaîne dans le claim groups, or Authelia retourne un tableau JSON. SFTPGo compare la valeur directement à "admin" — le tableau ne correspond jamais.

Correctif : user_attribute CEL dans Authelia ("sftpgo_admin" in groups ? "admin" : "user") + ROLE_FIELD=sftpgo_role.

Correctif 2 — Syntaxe custom_claims invalide

Symptôme : claim sftpgo_role absent du token malgré la configuration.

Cause : custom_claims: sftpgo_role: {} — syntaxe invalide, ignorée silencieusement par Authelia 4.39.

Correctif : custom_claims: sftpgo_role: attribute: sftpgo_role

Correctif 3 — Scope dédié requis pour les custom claims

Symptôme : claim toujours absent même avec la syntaxe corrigée.

Cause : dans Authelia 4.38+, les custom claims ne sont inclus dans le token que s'ils sont associés à un scope dédié déclaré dans identity_providers.oidc.scopes.

Correctif : ajout du scope sftpgo avec claims: [sftpgo_role] + scope ajouté à la liste du client.

Correctif 4 — Scope sftpgo non autorisé dans la liste du client

Symptôme : error=invalid_scope — The OAuth 2.0 Client is not allowed to request scope 'sftpgo' (logs nginx files.ncls.ltd).

Cause : un multi_replace_string_in_file précédent avait silencieusement echoué sur la liste des scopes du client en raison de matches multiples.

Correctif : remplacement avec contexte étendu → - sftpgo ajouté dans clients[0].scopes.

Correctif 5 (final) — implicit_roles : abandon du système sftpgo_role

Symptôme : après tous les correctifs précédents, Incorrect OpenID role, logged in user is an administrator côté client pour nico.

Cause : avec ROLE_FIELD=sftpgo_role retournant "admin", SFTPGo refuse l'accès à l'interface client. Le champ role_field est binaire et mutuellement exclusif — un utilisateur ayant le rôle admin ne peut pas accéder au client, même s'il possède aussi une entité user dans la BDD SFTPGo. La contrainte est inhérente au design de SFTPGo.

Solution finaleIMPLICIT_ROLES=true :

# docker-compose.yml
SFTPGO_HTTPD__BINDINGS__0__OIDC__IMPLICIT_ROLES=true
# ROLE_FIELD supprimé
# SCOPES simplifié : openid,profile,email

Avec implicit_roles: true, SFTPGo détermine le rôle en cherchant si le username OIDC existe comme entité admin ou user dans sa propre BDD :

  • /web/admin/login → vérifie si nico est un admin SFTPGo → ✅
  • /web/client/login → vérifie si nico est un user SFTPGo → ✅
  • /web/client/login → alice n'est pas admin → accès client ✅

Tout le système user_attribute CEL + custom_claims + scope sftpgo a été supprimé. La config Authelia est revenue à l'état minimal : claims_policy avec preferred_username + email uniquement, scopes openid profile email.


3. Actions Restantes

3.1 [UTILISATEUR] Changer le mot de passe temporaire d'alice

Alice a été créée dans Authelia avec le mot de passe temporaire e6lHH92W06c5pKrA. À changer via le portail Authelia : - URL : https://auth.ncls.ltd - Connexion avec le compte alice - Section « Change Password »

Alternativement, via le host :

# Générer un hash argon2id
pct exec 103 -- docker exec authelia authelia crypto hash generate argon2 --password 'NOUVEAU_MOT_DE_PASSE'
# Mettre à jour le hash dans /mnt/lxc-data/103-network/authelia/users_database.yml
# Redémarrer Authelia
pct exec 103 -- docker restart authelia

3.2 [OPTIONNEL] Monter /mnt/media dans SFTPGo

Pour que nico-admin ait accès à /mnt/media via SFTPGo :

  1. Ajouter dans /etc/pve/lxc/106.conf :

    mp6: /mnt/media,mp=/mnt/media,ro=1
    

  2. Ajouter dans docker-compose.yml :

    volumes:
      - /mnt/media:/media:ro
    

  3. Créer le virtual folder media dans SFTPGo et l'assigner sur le compte user nico.

3.3 [OPTIONNEL] Vhost nginx sftpgo-admin.internal (port 8080)

Le port 8080 est accessible en direct sur LAN (192.168.1.106:8080) mais pas exposé via nginx. Si accès VPN souhaité avec un nom de domaine :

server {
    listen 443 ssl;
    server_name sftpgo-admin.ncls.ltd;   # ou sous-domaine interne
    allow 10.0.0.0/8;   # WireGuard VPN
    allow 192.168.1.0/24;
    deny all;
    ssl_certificate /etc/letsencrypt/live/ncls.ltd/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ncls.ltd/privkey.pem;
    include /etc/nginx/snippets/ssl-params.conf;
    location / {
        proxy_pass http://192.168.1.106:8080;
        include /etc/nginx/snippets/proxy-params.conf;
    }
}

4. Bilan Technique — Intégration SFTPGo OIDC

4.1 Difficulté de mise en place

L'intégration SFTPGo ↔ Authelia OIDC s'est avérée significativement plus complexe que prévu. Au total, 5 sources d'erreurs en cascade pour la seule fonctionnalité « rôle admin OIDC » :

Problème Difficulté Visibilité
config_url ≠ well-known URL (§2.2) Faible Erreur explicite dans les logs SFTPGo
DNS interne Docker (§2.3) Modérée Erreur confuse (server misbehaving)
preferred_username absent de l'ID token (§2.4) Modérée Erreur explicite SFTPGo
Rôle admin — 5 correctifs cascade (§2.5) Élevée Chaque correctif révélait le suivant ; certains échecs silencieux (YAML ignoré, multi-replace sans match unique)

Facteurs aggravants : - SFTPGo ne logue pas le contenu du token OIDC reçu — impossible de déboguer sans authelia debug oidc claims - Authelia ignore silencieusement la syntaxe custom_claims: sftpgo_role: {} sans erreur de validation - L'outil multi_replace_string_in_file peut échouer silencieusement sur des matches multiples - L'ordre de démarrage est contraignant : si SFTPGo démarre avant qu'Authelia soit healthy, il crashe en boucle et finit par démarrer sans initialiser le provider OIDC — tous les logins échouent ensuite sans erreur claire

Commandes de diagnostic utiles :

# Vérifier le contenu réel du token OIDC
pct exec 103 -- docker exec authelia authelia debug oidc claims nico
# Vérifier les scopes annoncés par le discovery
curl -s https://auth.ncls.ltd/.well-known/openid-configuration | jq .scopes_supported
# Voir les erreurs OIDC côté nginx
grep -E 'error=' /mnt/lxc-data/103-network/nginx/logs/files.ncls.ltd_access.log | tail -10

4.2 Problématiques persistantes

Problème Sévérité Nature Solution
WebDAV : Basic Auth uniquement (pas OIDC) Fonctionnelle Inhérent au protocole WebDAV + SFTPGo v2.7.1 Aucune — mot de passe local SFTPGo requis
Interface admin local (port 8080) : LAN/VPN uniquement Acceptable Pas de vhost nginx exposé Optionnel : ajouter vhost nginx (§3.3)
Alice : mot de passe temporaire Authelia non changé ⚠️ À faire Action utilisateur requise Voir §3.1
/mnt/media non monté dans SFTPGo Hors scope Volume non configuré Voir §3.2
Ordre de restart Authelia → SFTPGo Contrainte opérationnelle Architecture OIDC (état provider en mémoire) Toujours attendre authelia healthy avant de recréer SFTPGo

4. Accès Distant — Montage Windows / Mac

WebDAV (recommandé — aucun logiciel tiers)

SFTPGo expose le WebDAV via webdavd (port 8091 interne) derrière nginx à https://files.ncls.ltd.

Pré-requis : un mot de passe local SFTPGo est requis pour WebDAV (Basic Auth). L'OIDC seul ne fonctionne pas pour WebDAV. Définir un mot de passe local via l'admin SFTPGo (http://192.168.1.106:8080) → Users → champ Password. Nico : Trzy2rKftdFDm5aN (défini le 2026-04-04, à conserver en §7). WebDAV path : https://files.ncls.ltd/dav/ — le chemin /dav est nécessaire pour éviter que le navigateur reçoive WWW-Authenticate: Basic sur / et affiche une boîte de dialogue native.

Windows 11 — Connexion en lecteur réseau

La méthode "Se connecter à un dossier web" de l'explorateur ne fonctionne pas avec Basic Auth sur HTTPS sans un correctif registre. Utiliser net use en PowerShell (plus fiable) :

# Mapper en lecteur réseau (admin facultatif)
net use Z: https://files.ncls.ltd/dav /user:nico Trzy2rKftdFDm5aN /persistent:yes

Si l'erreur « Accès refusé » apparaît, appliquer d'abord le correctif registre :

# Activer Basic Auth sur HTTPS (valeur 2 = autorisé sur HTTPS uniquement)
# Ouvrir PowerShell en administrateur
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\WebClient\Parameters" `
  -Name "BasicAuthLevel" -Value 2
Restart-Service WebClient

Pour les uploads > 50 MB (limite Windows par défaut) :

Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\WebClient\Parameters" `
  -Name "FileSizeLimitInBytes" -Value 0xFFFFFFFF
Restart-Service WebClient

macOS : 1. Finder → Aller → Se connecter au serveur (⌘K) 2. URL : https://files.ncls.ltd/dav 3. Identifiants : nico + mot de passe local SFTPGo 4. Le disque apparaît dans le Finder sous /Volumes/files.ncls.ltd

SFTP (clients tiers — performances supérieures pour gros transferts)

Client Plateforme Config
WinSCP Windows Hôte: files.ncls.ltd, port: 2022, protocole: SFTP, user: nico, auth: clé SSH ou password local
Cyberduck Windows/Mac Profil SFTP, même paramètres
FileZilla Windows/Mac/Linux Idem
Finder/Terminal macOS sftp nico@files.ncls.ltd -p 2022

Le port SFTP 2022 doit être ouvert en entrée sur le routeur/firewall si accès depuis l'extérieur du LAN.

Résumé des protocoles disponibles

Protocole Port URL Usage recommandé
HTTPS (web UI) 443 https://files.ncls.ltd Navigation, upload/download ponctuel, partage de liens
WebDAV 443 https://files.ncls.ltd/dav Montage disque Windows/Mac
SFTP 2022 files.ncls.ltd:2022 Transferts massifs, scripts, CLI

5. Rapatriement des Archives (Disque Externe HGST)

Correspond à la Phase 6 du spec. Trois approches possibles selon le contexte.

Option A — Via PC avec disque monté en WebDAV (recommandé pour un utilisateur non-technique)

Scénario : le disque HGST est branché sur un PC Windows ou Mac. SFTPGo est monté en lecteur réseau WebDAV.

  1. Brancher le disque HGST sur le PC
  2. Monter https://files.ncls.ltd comme lecteur réseau (voir §4 ci-dessus)
  3. Copier-coller via l'Explorateur Windows / Finder depuis le HGST vers le lecteur réseau :
  4. HGST:/alice/Z:\alice\archives\
  5. HGST:/nico/Z:\nico\archives\
  6. HGST:/commun/Z:\family\archives\
  7. Vérifier l'intégrité via l'interface web SFTPGo

Inconvénient : débit limité par le WebDAV + réseau local (typiquement 50–100 MB/s sur Gigabit). Pour 1 TB, compter 3–6h.

Option B — Via Web UI SFTPGo (upload direct)

Scénario : accès à https://files.ncls.ltd depuis un navigateur, disque HGST branché sur le PC.

  1. Se connecter à https://files.ncls.ltd (OIDC Authelia)
  2. Naviguer dans archives/
  3. Utiliser le bouton « Upload » — glisser-déposer les dossiers

Limitation : l'upload via navigateur ne supporte pas bien les arborescences complexes. Adapté pour des lots de fichiers, pas pour migrer 1 TB d'un coup. Pas de reprise sur interruption.

Option C — Via ligne de commande sur le host Proxmox (recommandé pour gros volumes)

Scénario : brancher le disque HGST directement sur le serveur Proxmox (USB 3.0).

# 1. Identifier le disque
lsblk

# 2. Monter
mkdir -p /mnt/hgst-ext
mount /dev/sdX1 /mnt/hgst-ext   # adapter sdX1 selon lsblk

# 3. Migrer (rsync local — débits disque, pas réseau)
rsync -avP /mnt/hgst-ext/alice/  /mnt/storage/alice/archives/
rsync -avP /mnt/hgst-ext/nico/   /mnt/storage/nico/archives/
rsync -avP /mnt/hgst-ext/commun/ /mnt/storage/family/archives/

# 4. Snapshot ZFS post-migration
zfs snapshot -r storage@post-migration-$(date +%Y%m%d)

# 5. Démonter
umount /mnt/hgst-ext

Avantages : débit USB 3.0 direct (100–200 MB/s), reprise sur interruption (rsync idempotent), snapshot ZFS immédiat après migration.

Recommandation : Option C si le HGST peut être branché physiquement au serveur. Option A sinon (PC + WebDAV). Option B uniquement pour des fichiers isolés.


6. Fichiers Créés / Modifiés

Fichier Action Contenu clé
zpool create storage /dev/sdd Créé Pool ZFS ashift=12, zstd, /mnt/storage
/etc/sanoid/sanoid.conf Créé Snapshots daily×7/weekly×4/monthly×3
/root/.config/rclone/rclone.conf Modifié [gdrive][gdrive-nico]
/usr/local/bin/backup-docker-configs.sh Modifié gdrive:gdrive-nico:
/usr/local/bin/backup-proxmox-host.sh Modifié gdrive:gdrive-nico:
/usr/local/bin/pull-gdrive.sh Créé Sync Drive nico + alice (conditionnel) + family
/etc/cron.d/pull-gdrive Créé 0 3 * * * root /usr/local/bin/pull-gdrive.sh
/etc/subuid, /etc/subgid Modifié root:1000:1 ajouté
/etc/pve/lxc/106.conf Créé idmap UID1000, mp0–mp5
/mnt/lxc-data/docker-106/docker-compose.yml Créé puis modifié SFTPGo v2.7.1, env OIDC, extra_hosts, port 8091 webdavd
/mnt/lxc-data/docker-103/authelia/configuration.yml Modifié Client OIDC sftpgo + claims_policy sftpgo_policy
/mnt/lxc-data/docker-103/nginx/conf.d/files.ncls.ltd.conf Créé puis modifié Routage /web\|/api/ → 8090 (httpd), / → 8091 (webdavd)

7. Secrets à Conserver

Secret Valeur Usage
OIDC client secret SFTPGo (plaintext) 1dk8qawmhMgS1VX5y1ICa3VISC8YTir5ahVa2WHbqMA= docker-compose.yml env var
OIDC client secret SFTPGo (argon2id) $argon2id$v=19$m=65536,t=3,p=4$2qU5WzFv5QFZc5Z2YNTvjw$79wiOlNu5X2QTBJo2Vyb+bus/1I3cT+6w0TRe65DhLo configuration.yml Authelia
Admin SFTPGo local nico / uFvEwW4GuoZdVY1akhq4g Admin web port 8080
WebDAV password nico Trzy2rKftdFDm5aN net use Z: https://files.ncls.ltd /user:nico