diff --git a/CLAUDE.md b/CLAUDE.md index 58c534c..89ba01f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -24,8 +24,7 @@ Recovery steps are in `RUNBOOK.md`. Repo overview and workflows are in `README.m ## Remotes -- **origin**: Gitea on argento (private) -- **GitHub mirror**: Push mirror configured in Gitea repo settings (survives if argento dies) +- **origin**: Gitea on argento (private). No offsite mirror — disaster recovery relies on the USB backup's copy of the Gitea bare repo. ## Working preferences diff --git a/IMMICH-MIGRATION.md b/IMMICH-MIGRATION.md new file mode 100644 index 0000000..2962cf9 --- /dev/null +++ b/IMMICH-MIGRATION.md @@ -0,0 +1,101 @@ +# Immich migration plan + +One-time migration of photos from Nextcloud into Immich's native library. + +- **Source:** `/opt/argento/docker/nextcloud/data/timothykim/files/Photos/` (338 GB, ~58k files) +- **Target:** Immich native library on `threeteras` pool (`/opt/argento/docker/immich/library/`) +- **Tool:** `immich-go` via Immich HTTP API +- **Expected wall time:** ~1 day if videos are short clips, 2–3 days if significant long/4K video + +## 1. Pause the backup cron (optional but recommended) + +```bash +crontab -e # comment out scripts/backup.sh line +``` + +Re-enable after migration completes. + +## 2. Install immich-go + +```bash +mkdir -p /opt/argento/tools && cd /opt/argento/tools +wget https://github.com/simulot/immich-go/releases/latest/download/immich-go_Linux_x86_64.tar.gz +tar xzf immich-go_Linux_x86_64.tar.gz +./immich-go --version +``` + +## 3. Get an Immich API key + +Immich UI -> Account Settings -> API Keys -> New (label it "migration"). Save the key. + +## 4. Get the direct container IP (skips nginx/TLS overhead) + +```bash +IMMICH_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}' immich_server | awk '{print $1}') +echo $IMMICH_IP +``` + +## 5. Dry-run on a small subfolder first + +Pick one year or album: + +```bash +./immich-go upload from-folder \ + --server http://$IMMICH_IP:2283 \ + --api-key \ + --dry-run \ + /opt/argento/docker/nextcloud/data/timothykim/files/Photos/ +``` + +## 6. Real run on that subfolder, verify in UI + +Drop `--dry-run`, run, then in Immich check: dates, GPS, thumbnails, album assignment look correct. + +## 7. Full migration in tmux + +```bash +tmux new -s immich-migrate +./immich-go upload from-folder \ + --server http://$IMMICH_IP:2283 \ + --api-key \ + --into-album-folder \ + /opt/argento/docker/nextcloud/data/timothykim/files/Photos/ +# Ctrl-b d to detach; tmux attach -t immich-migrate to resume +``` + +Safe to Ctrl-C and re-run -- idempotent by file hash. + +## 8. Wait for background jobs + +Immich UI -> Administration -> Jobs. Watch these drain (can take hours to days): + +- Thumbnail Generation +- Metadata Extraction +- Smart Search (CUDA) +- Face Detection + Recognition (CUDA) +- Video Conversion (NVENC) + +## 9. Verify counts + +```bash +find /opt/argento/docker/nextcloud/data/timothykim/files/Photos/ -type f | wc -l +# Compare to Immich UI -> Administration -> Server Stats +``` + +If mismatch, re-run step 7 (will only upload the missing files). + +## 10. Spot-check the library + +Random samples across years, verify EXIF dates, GPS locations, faces grouping reasonably. + +## 11. Clean up Nextcloud (only after you're satisfied) + +Delete `Photos/` from Nextcloud UI -> empty trashbin -> verify `zfs list` shows `nextcloud/data` shrank. + +## 12. Re-enable backup cron + +Uncomment the cron line, then run `scripts/backup.sh` manually once to get a fresh full backup with the new Immich library. + +## Rollback + +If anything goes wrong before step 11, Nextcloud is untouched. Worst case: delete all Immich assets from UI (or wipe `/opt/argento/docker/immich/library/` and reinit the DB), start over. diff --git a/README.md b/README.md index 0177186..7332331 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ See [RUNBOOK.md](RUNBOOK.md) for full disaster recovery steps. | Data | Protection | Recovery | |------|-----------|----------| -| Configs (compose, nginx, system) | Git (Gitea + GitHub mirror) | `git clone` | +| Configs (compose, nginx, system) | Git (Gitea bare repo on USB backup) | `git clone` from USB | | Nextcloud files | ZFS mirror + sanoid snapshots + USB | `rsync` from USB | | Media library | ZFS raidz2 + sanoid snapshots + USB | `rsync` from USB | | Nextcloud DB (PostgreSQL) | ZFS dataset + `pg_dumpall` + USB | `rsync` from USB | diff --git a/RUNBOOK.md b/RUNBOOK.md index 7e9922b..3629a0a 100644 --- a/RUNBOOK.md +++ b/RUNBOOK.md @@ -69,10 +69,8 @@ mount /mnt/backup ## 6. Get the repo ```bash -git clone https://github.com//argento-server.git /opt/argento - -# If GitHub is unavailable, clone from the Gitea bare repo on the USB backup: -# git clone /mnt/backup/argento/docker/gitea/data/git/repositories/timothykim/argento.git /opt/argento +# Clone from the Gitea bare repo on the USB backup +git clone /mnt/backup/argento/docker/gitea/data/git/repositories/timothykim/argento.git /opt/argento ``` Clone first -- ZFS datasets will mount into this directory tree in the next step.