diff --git a/g9-migration/PHASE4-RECOLLEMENT.md b/g9-migration/PHASE4-RECOLLEMENT.md index 68d5161..a2de97b 100644 --- a/g9-migration/PHASE4-RECOLLEMENT.md +++ b/g9-migration/PHASE4-RECOLLEMENT.md @@ -18,7 +18,7 @@ | Jellyfin (T4.5) | `jellyfin/jellyfin:10.9` (10.9.11) | healthy, média par RÉFÉRENCE (`/mnt/usb-media` → `/media:ro`, aucune copie), 1 médiathèque = `/media/films`, Items Movie = 1 | false | | edge (T4.6) | `caddy:2` (digest `f2a1290d…`) | healthy, HTTPS interne (CA interne), 443 seul port exposé WAN | **true** (stateless) | | Watchtower (T4.7) | `nickfedor/watchtower@sha256:45b54f6d…` | healthy, scope label-enable : dry-run `scanned=2` (edge + watchtower), 14 stateful ignorés | true | -| PhotoPrism (T4.3) | — | **non déployée** : `07d-migrate-photoprism.sh` écrit/testé, exécution reportée (coût = copie 530 Go ; média servi par Jellyfin) | — | +| PhotoPrism (T4.3) | `photoprism/photoprism:260919` + `mariadb:10.11` | **✅ 12/10** : 433 941 fichiers / 567 Go copiés depuis `/volume1/photo` (manifeste chemins+tailles 0 écart, sha256 200/200), stack healthy port 2342 (LAN) + `photos.folzocorp.fr` via edge J5040 ; index progressif (AUTO_INDEX 300 s, chaîne index→faces→analyze) ; snapshot restic + restore photo prouvée (`10-verify-restore-photo.sh`) | false | ### 0.2 Incidents rencontrés et correctifs (détail = journal.md) @@ -41,6 +41,15 @@ - `nextcloud_app`, `nextcloud_db`, `nextcloud_redis`, `vaultwarden-server-1`, `gitea` **relancés et up** après les exports ; dumps/transitaires supprimés sur .25, pilot et G9. - Aucun partage, aucune donnée, aucun conteneur .25 supprimé ; transports .25→pilot = `ssh 'sudo tar cz'`/`mysqldump` en lecture seule (sshd DSM refuse `rsync --server` et scp). +### 0.5 J5040 (.27) — E1→E4 (11–12/10) + +| Étape | État | Preuve | +|---|---|---| +| E1 durcissement | ✅ | SSH clés-only, ufw (LAN 53/3000/8081 + WAN 80/443/51820), fail2ban, unattended-upgrades, Docker 29.1.3 ; RAM 8 Go sous test (upgrade 16 Go si > 70 %) | +| E2 AdGuard | ✅ bascule faite | `adguard/adguardhome` (digest `aba9e3bf…`) sur .27, UI 8081, DNS 53 ; config VM .1 migrée (2 filtres 182 128 + 6 540 règles, safe_search, profils parents, users bcrypt) ; resolvants clients → .27 ; filtrage testé ; VM .1 conservée secours | +| E3 DHCP | préparé, **GO utilisateur (G6)** | baux statiques Freebox repris (35 appareils, OCR 38) dans `/srv/dnsmasq/leases`, `dnsmasq --test` OK, script `09-j5040-dhcp.sh` prêt ; bascule = Freebox Pop + dnsmasq | +| E4 edge + WireGuard | certs ✅, **GO utilisateur pour WAN** | Caddy OVH DNS-01 (plugin `maxcryger/caddy-ovh` digest `502996b5…`) : **7/7 certs LE** + proxy 6 briques (photos 307 depuis 12/10) ; WireGuard `wg0.conf` + client prêts (600, gitignorés) ; forward WAN Freebox→.27 et démontage edge G9 = après GO | + --- # Rapport de récupération (thread supprimé) diff --git a/g9-migration/README.md b/g9-migration/README.md index ba0a1b6..08e8169 100644 --- a/g9-migration/README.md +++ b/g9-migration/README.md @@ -62,6 +62,7 @@ g9-migration/ │ ├── 07e-deploy-edge.sh ← T4.6 : edge Caddy (validate → up → ufw 443 → vérifs HTTPS/SNI) │ ├── restic-notify.sh ← alerte Matrix des jobs restic (posée par 06) │ ├── 09-j5040-dhcp.sh ← E3 : DHCP dnsmasq sur J5040 (pré-bascule bridge) +│ ├── 10-verify-restore-photo.sh ← critère 3 : preuve restore photo (sha256 vs .25) │ └── 08-decommission.sh ← T6.4 : décommissionnement xpenology [DESTRUCTIF] ├── compose/ ← docker-compose.yml versionnés (stockés aussi dans Gitea) │ ├── vaultwarden/ ← T4.1 @@ -86,9 +87,9 @@ g9-migration/ | 1 | (xpenology) exclure stateful de Watchtower + inventaire | G4 | | 2 | `01-hardening.sh` → `02-data.sh` → `03-docker.sh` → `03b-secrets.sh` → `04-smb.sh` → `05-beszel.sh` | — | | 3 | `06-restic-backup.sh` (backup + test restauration) | G2 | -| 4 | **par brique, dans l'ordre** — **après** `03b-secrets.sh` : `07b-migrate-vaultwarden.sh` (T4.1) → `07c-migrate-nextcloud.sh` (T4.2) → `07d-migrate-photoprism.sh` (T4.3, **en cours 11/10** — copie 567 Go sans gzip) → `07a-migrate-gitea.sh` (T4.4) → Jellyfin (T4.5, frais) → `07e-deploy-edge.sh` (T4.6, Caddy TLS interne) → Watchtower (T4.7, scope stateless). `07-migrate-stateful.sh` = script **générique rsync**, inopérant sur le DSM (sshd refuse `rsync --server`/scp) ; transport réel des 07a–07d = **tar sur SSH** | G4 | +| 4 | **par brique, dans l'ordre** — **après** `03b-secrets.sh` : `07b-migrate-vaultwarden.sh` (T4.1) → `07c-migrate-nextcloud.sh` (T4.2) → `07d-migrate-photoprism.sh` (T4.3) **✅ 12/10** : 433 941 fichiers / 567 Go copiés, manifeste 0 écart + sha256 200/200, stack up (port 2342), index progressif, snapshot restic + restore prouvée (`10-verify-restore-photo.sh`) → `07a-migrate-gitea.sh` (T4.4) → Jellyfin (T4.5, frais) → `07e-deploy-edge.sh` (T4.6, Caddy TLS interne) → Watchtower (T4.7, scope stateless). `07-migrate-stateful.sh` = script **générique rsync**, inopérant sur le DSM (sshd refuse `rsync --server`/scp) ; transport réel des 07a–07d = **tar sur SSH** | G4 | | 5 | restic 3-2-1 complet (G9 + PC IA → Freebox → 218play) | G2 | -| E (J5040, parallèle) | **E1** durcissement + Docker (`01`/`03` paramétrés, .27) ✅ → **E2** AdGuard (VM Freebox .1 → .27, config migrée) ✅ déploiement, bascule DNS en attente → **E3** DHCP (`09-j5040-dhcp.sh`) + Freebox **mode bridge** (validation utilisateur G6) → **E4** Caddy OVH (`compose/edge-j5040`, LE DNS-01) + WireGuard, puis démontage edge G9 | G6, G7 | +| E (J5040, parallèle) | **E1** durcissement + Docker (`01`/`03` paramétrés, .27) ✅ → **E2** AdGuard (VM Freebox .1 → .27) ✅ bascule DNS faite (résolvants clients → .27, filtres testés) → **E3** DHCP (`09-j5040-dhcp.sh`, baux 35 appareils prêts) + Freebox **mode bridge** = **GO utilisateur (G6)** → **E4** Caddy OVH (`compose/edge-j5040`) ✅ 7/7 certs LE (DNS-01) + WireGuard prêt ; forward WAN Freebox→.27 + démontage edge G9 = **GO utilisateur** | G6, G7 | | 6 | `06b-usb-media.sh` (T6.1) → Jellyfin (T6.2) → IP .24→.25 → `08-decommission.sh` | G3, G4, G5 | | 7 | (G7) wipe DSM + Ubuntu neuf + boot test | G3, G10 | diff --git a/g9-migration/journal.md b/g9-migration/journal.md index a3e590e..6874b1d 100644 --- a/g9-migration/journal.md +++ b/g9-migration/journal.md @@ -122,3 +122,5 @@ | 2026-10-12 14:06 | 4 | migrate:photoprism : intégration PhotoPrism | copie de 530 Go à vérifier avant indexation | manifeste chemins+tailles identique (433941 fichiers, 567394182751 o) + échantillon sha256 200/200 | re-copie ciblée via tar/ssh | | 2026-10-12 14:11 | 4 | migrate:photoprism : intégration PhotoPrism | copie de 530 Go à vérifier avant indexation | manifeste chemins+tailles identique (433941 fichiers, 567394182751 o) + échantillon sha256 200/200 | re-copie ciblée via tar/ssh | | 2026-10-12 14:17 | 4 | migrate:photoprism : intégration PhotoPrism | copie de 530 Go à vérifier avant indexation | manifeste chemins+tailles identique (433941 fichiers, 567394182751 o) + échantillon sha256 200/200 | re-copie ciblée via tar/ssh | +| 2026-10-12 14:18 | 4 | migrate:photoprism : stack PhotoPrism déployée + indexation lancée | T4.3 : stack saine, index progressif (photothèque 530 Go sur le G9) | image épinglée 260919, MariaDB 10.11 (watchtower OFF), secrets via env_file 600, port 2342 LAN ; originals = copie locale | docker compose down + rm -rf /data/docker/photoprism | +| 2026-10-12 15:07 | 4 | test restauration photo depuis restic | Critère 3 : preuve restore du snapshot incluant les photos | snapshot 06a7e3b89ef3e97d5f5c1dc9098496fab8ad79d48f4455eabdde07255143e33b contient 505836 entrées sous /data/docker/photoprism/originals ; restore 1 fichier ; sha256 restauré == source .25 (00cbfed8da81…) ; chiffrement maintenu (clé locale G9) | rm -rf /tmp/restore-photo-test (fait) | diff --git a/g9-migration/scripts/07d-migrate-photoprism.sh b/g9-migration/scripts/07d-migrate-photoprism.sh index 633bdf1..5d34908 100755 --- a/g9-migration/scripts/07d-migrate-photoprism.sh +++ b/g9-migration/scripts/07d-migrate-photoprism.sh @@ -125,8 +125,8 @@ $SSH_G9 "cd $G9_DIR && sudo docker compose up -d && sleep 30 && sudo docker comp # ---------------------------------------------------------------- 5. indexation + vérifs log "=== 5/5 INDEXATION (progressive, décision #4) + VÉRIFS ===" $SSH_G9 "curl -s -o /dev/null -w 'photoprism HTTP %{http_code}\n' http://127.0.0.1:2342/api/v1/health" -$SSH_G9 "cd $G9_DIR && timeout $INDEX_TIMEOUT sudo docker compose exec -T photoprism photoprism index 2>&1 | tail -6 < /dev/null || true" -$SSH_G9 "cd $G9_DIR && sudo docker compose exec -T photoprism sh -c 'photoprism count 2>/dev/null | head -12' < /dev/null || true" +$SSH_G9 "cd $G9_DIR && timeout $INDEX_TIMEOUT sudo docker compose exec -T photoprism photoprism index < /dev/null 2>&1 | tail -6 || true" +$SSH_G9 "cd $G9_DIR && sudo docker compose exec -T db sh -c 'mariadb -u photoprism -p\"\$(cat /run/secrets/dbpass)\" photoprism -e \"SELECT COUNT(*) AS photos_indexes FROM photos\"' 2>/dev/null || true" journal "stack PhotoPrism déployée + indexation lancée" "T4.3 : stack saine, index progressif (photothèque 530 Go sur le G9)" "image épinglée 260919, MariaDB 10.11 (watchtower OFF), secrets via env_file 600, port 2342 LAN ; originals = copie locale" "docker compose down + rm -rf /data/docker/photoprism" echo diff --git a/g9-migration/scripts/10-verify-restore-photo.sh b/g9-migration/scripts/10-verify-restore-photo.sh index 925f261..b9546e4 100755 --- a/g9-migration/scripts/10-verify-restore-photo.sh +++ b/g9-migration/scripts/10-verify-restore-photo.sh @@ -29,7 +29,7 @@ journal() { log "=== 1/3 snapshot g9 le plus récent ===" SNAP=$($SSH_G9 "sudo bash -s" </dev/null | jq -r '.[-1].id' EOF ) [[ "$SNAP" =~ ^[0-9a-f]{8,}$ ]] || { echo "ERREUR : snapshot introuvable"; exit 1; } @@ -46,7 +46,7 @@ log " ✅ snapshot contient $N entrées sous $G9_ORIG" log "=== 2/3 restauration d'un fichier photo ===" G9_META="${HOME}/migration-staging/photoprism/g9.meta" if [[ -f "$G9_META" ]]; then - REL=$(grep -i '\.jpg$' "$G9_META" | cut -f1 | LC_ALL=C sort | tail -1) + REL=$(cut -f1 "$G9_META" | grep -i '\.jpg$' | LC_ALL=C sort | tail -1) REL="${G9_ORIG}/${REL#./}" else REL=$($SSH_G9 "find '$G9_ORIG' -type f -iname '*.jpg' | LC_ALL=C sort | tail -1") @@ -57,11 +57,11 @@ $SSH_G9 "sudo bash -s -- '$B64' '$SNAP' '$TARGET'" <<'EOF' set -a; . /etc/restic.env; set +a rel=$(printf '%s' "$1" | base64 -d) rm -rf "$3" -restic -r "$RESTIC_REPOSITORY" restore --target "$3" --path "$rel" "$2" >/dev/null +restic -r "$RESTIC_REPOSITORY" restore --target "$3" --include "*${rel##*/}" "$2" >/dev/null EOF $SSH_G9 "sudo bash -s -- '$B64' '$TARGET'" <<'EOF' || { echo "ERREUR : fichier restauré absent"; exit 1; } rel=$(printf '%s' "$1" | base64 -d) -test -f "$2${rel#/}" +test -f "$2$rel" EOF log "=== 3/3 sha256 restauré vs source .25 ===" H_SRC=$($SSH_XP "sudo bash -s -- '$B64' '$XP_PHOTO'" <<'EOF' @@ -71,7 +71,7 @@ EOF ) H_RST=$($SSH_G9 "sudo bash -s -- '$B64' '$TARGET'" <<'EOF' f=$(printf '%s' "$1" | base64 -d) -sudo sha256sum "$2${f#/}" | cut -d' ' -f1 +sudo sha256sum "$2$f" | cut -d' ' -f1 EOF ) $SSH_G9 "sudo rm -rf '$TARGET'"