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 owners — home_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_foldersdoit être placé au niveau racine du groupe (pas dansuser_settings). Le champuser_settings.virtual_foldersest 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-recreatede 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 unping -I eth0depuis 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 :
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 finale — IMPLICIT_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 sinicoest un admin SFTPGo → ✅/web/client/login→ vérifie sinicoest 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 :
-
Ajouter dans
/etc/pve/lxc/106.conf: -
Ajouter dans
docker-compose.yml: -
Créer le virtual folder
mediadans 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/davest nécessaire pour éviter que le navigateur reçoiveWWW-Authenticate: Basicsur/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.
- Brancher le disque HGST sur le PC
- Monter
https://files.ncls.ltdcomme lecteur réseau (voir §4 ci-dessus) - Copier-coller via l'Explorateur Windows / Finder depuis le HGST vers le lecteur réseau :
HGST:/alice/→Z:\alice\archives\HGST:/nico/→Z:\nico\archives\HGST:/commun/→Z:\family\archives\- 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.
- Se connecter à
https://files.ncls.ltd(OIDC Authelia) - Naviguer dans
archives/ - 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 |