Q19 resolved: storage convention is plain host bind-mount, not SMB volume

The Karakeep compose user shared confirms every container in LXC 104
uses host bind-mounts of /mnt/pve/unas/services/<svc>/<vol> directly.
No driver_opts, no CIFS, no per-volume credentials. The earlier
SMB-as-docker-volume proposal in this repo was over-fitting to the
Nextcloud-specific NFS issue and is withdrawn.

The Nextcloud failure was Nextcloud-specific: its setup tooling chowns
the data dir to www-data, which fails against root_squash exports.
Normal containers don't trigger that path, so plain bind-mounts work
fine.

Changes:

- docs/09 §Step 3: compose block dropped from ~30 lines (volume,
  driver_opts, CIFS device, credentials env) to a one-line bind-mount
  + env_file. Added a pre-deploy `mkdir -p` for the UNAS service +
  backup paths. Explanatory note retained for future agents.
- docs/12 #27 marked withdrawn pointing to #31. #31 rewritten with the
  bind-mount pattern (was SMB-default). #36 (UNAS audit) now looks for
  `- /var/lib/docker/...` or anonymous volumes as the non-compliant
  signal.
- CLAUDE.md storage block: bind-mount is the standard, SMB is
  documented escape-hatch only.
- docs/11: Q19 moved into Resolved with the new framing. Q12 + Q20
  grouped under a new "## Backups" section header (the now-empty
  "Verification needed" section removed).
- docs/13 Task 1 struck through with done-marker pointing to docs/09.

Net: Phase-3.1 deployment YAML is now actually deployable as written.
This commit is contained in:
Claude
2026-05-05 05:01:48 +00:00
parent dfd9aa7d2a
commit a8446f8371
5 changed files with 38 additions and 59 deletions
+3 -5
View File
@@ -17,6 +17,7 @@ Items that **block progress** and need a human decision before a workflow can be
- [x] **Q16 — Image-attachment queue ergonomics → leave bytes at source, reference by `media_uri`.** Zero copy. Memos attachments stay in Memos's data dir, Nextcloud images stay in Nextcloud, Obsidian images stay in the `Notizen` folder; the Phase-3.2 backfill workflow fetches them on demand via the URI scheme.
- [x] **Q17 — Immich out-of-band.** Nexa does not call the Immich smart-search API. Photo-library queries stay inside Immich.
- [x] **Q18 — SAIA proxies an embedding model, but 10 msg/min rate limit makes it unusable for ingest.** A 2 k-note Obsidian backfill would take ~3.3 h; real-time `#nexa:ask` would queue for tens of seconds during a writing burst. **Decision: deploy TEI as planned.** SAIA embeddings remain available as a manual fallback (e.g. for one-off `#nexa:learn` calls where rate is irrelevant).
- [x] **Q19 — Storage convention is plain host bind-mount of `/mnt/pve/unas/services/<svc>/<vol>`.** Karakeep stack confirmed: no driver opts, no CIFS, no per-volume credentials. Secrets via `env_file: .env` next to the compose. The earlier SMB-as-docker-volume proposal in this repo is withdrawn ([12/#27](./12-optimization-opportunities.md#27)) — it was over-fitting to the Nextcloud-specific NFS issue (Nextcloud's setup tooling chowns to `www-data` and fails on `root_squash`-style exports; that doesn't apply to normal containers). Nexa stack updated in [docs/09 §Step 3](./09-deployment.md#step-3--self-hosted-embeddings-tei).
- [x] **Q4 — Obsidian sync via Nextcloud WebDAV.** Confirmed the vault is `nc.nuclide.systems/Notizen/` (multi-device sync via Nextcloud client). Nexa accesses it through WebDAV (`/remote.php/dav/files/<user>/Notizen/`) reusing the existing `NC_APP_PASSWORD` — no filesystem mount, no LXC-to-LXC privilege escalation. Phase 3.1 polls every 15 min; an upgrade to Nextcloud's `notify_push` for sub-second updates is captured as optimization #15. Ignore list (don't index):
- `.copilot/`, `.copilot-index/` — Obsidian Copilot's own embeddings cache.
- `.smart-env/` — Smart Connections / Smart Composer plugin data (~13 MB).
@@ -49,12 +50,9 @@ Items that **block progress** and need a human decision before a workflow can be
- **RAM headroom is comfortable**: Phase-3 budget (~7 GiB additional — Qdrant ~1.5 + TEI/bge-m3 ~1.1 + GraphDB 4-GB heap + later +infinity/jina-clip-v2 ~1) fits inside the existing LXC cap with ~16 GiB still free. Levers if needed: (1) raise the LXC cap (host has plenty), (2) cap `zfs_arc_max` lower (ARC currently 24 GiB). Either is one line of config.
- **Disk is fine** — the LXC also NFS-mounts the UNAS at `/mnt/pve/unas` (19.4 TiB total, 16.3 TiB free). Large/persistent volumes (Qdrant data, GraphDB repo, snapshots, image bytes if we ever stage them) bind-mount there; the 200 GiB local boot disk only carries images and small ephemeral state. See [12/#27](./12-optimization-opportunities.md#27).
- **Verdict: no blockers for Phase-3.1.** Revisit once 3.4 GraphDB lands.
- [ ] **Q12 — S3 archive bucket.** `s3.nuclide.systems` is up. Bucket name + access key for Qdrant snapshots and GraphDB exports?
## Verification needed before Phase-3.1 deploy
- [ ] **Q19 — Confirm the SMB share name + mount syntax** by reading an existing stack in **Arcane** (recommended: `karakeep` or `immich`). The SMB share name on UNAS that maps to the NFS root `/var/nfs/shared/storage` is currently a placeholder `<unas-share>` in [docs/09](./09-deployment.md). Required action: open the running Karakeep stack in Arcane, copy its `volumes:` block verbatim, swap `karakeep``nexa` in the path, drop into the Nexa stack. This locks Nexa to the **same convention every other container in the homelab uses** — same driver, same credentials secret, same uid/gid — and avoids reinventing storage just for Nexa.
## Backups
- [ ] **Q12 — S3 archive bucket** (warm tier). `s3.nuclide.systems` is up. Bucket name + access key for Qdrant snapshots, GraphDB exports, and as the rsync source for the cold-tier copy.
- [ ] **Q20 — Off-site cold-tier backup provider.** `s3.nuclide.systems` is on-site only, so today the homelab has no real disaster-recovery copy (fire / theft / ransomware kills it). Comparison + recommendation in [docs/12 #37](./12-optimization-opportunities.md#37). User's stated candidate is **Jottacloud Unlimited** (~€9.50/mo, EU/Norway, soft-cap ~5 TB — comfortable for the next ~10 years given current 2 TB and slow growth). Alternatives: Hetzner Storage Box BX21 (€13/mo, predictable quota), Backblaze B2 (~$12/mo, US, S3-compatible). **Always encrypt before upload** with `restic` or `rclone crypt` regardless of provider. Decision needed: pick one, create the account, share account email here (no password). Once chosen, optimization #37 can be implemented end-to-end.
---