9b18e2710d
- /docs/ now contains 12 numbered guides + index.md (navigator).
- Old duplicates removed: nexa-core/doc/, DEPLOYMENT.md, PLAN.md,
config/{classification_logic,workflows_spec}.md.
- 09-deployment.md targets the running infra (LXC 104 docker host,
Zoraxy at 192.168.1.4, existing Memos/n8n/LiteLLM/Nextcloud/Qdrant)
rather than spinning a parallel stack; minimal-config approach.
- 11-open-questions.md tracks user-info-required blockers.
- 12-optimization-opportunities.md captures homelab tweaks.
- CLAUDE.md added so future agent runs know repo conventions and infra.
3.7 KiB
3.7 KiB
12 — Optimization Opportunities
Observations from the running infrastructure. Each item is independent — accept, defer, or reject.
For Nexa directly
- Reuse, don't redeploy. The earlier
DEPLOYMENT.mdwould have spun a second Memos / n8n / Qdrant. The current homelab already runs all three. The new 09-deployment treats these as pre-existing — keeps the config minimal and avoids port collisions. - Use LiteLLM virtual keys per logical caller. Today there's one SAIA key. Issuing one key per workflow (
nexa-router,nexa-embed,nexa-digest) lets you set different per-key rate/cost limits and disable a single workflow without rotating everything. - Use n8n's credential objects, never inline secrets. The current workflows under
nexa-core/n8n-workflows/phase-1/*.jsonshould be reviewed — if any headerAuthorizationis hardcoded, replace with credential references before importing. - Centralise system alerts on a single ntfy topic (
nexa.system). Backrest, Proxmox notifications, n8n failure-webhook and the Octoprint Exited state all go to that topic; one Memos system memo aggregates them. - Defer graph DB until Phase 3.4. Qdrant alone covers ~80% of the assistant's daily value. The graph DB is justified once you actually need dependency analysis or critical-path queries.
- Auto-export n8n workflows.
nexa-core/scripts/backup_workflows.shalready exists. Schedule it inside the n8n container (cron) and let itgit commit && git push— this is the cheapest disaster recovery.
For the wider homelab (out of scope but worth noting)
- Octoprint
EXITED— either remove the Homepage entry or fix the container; right now it permanently shows red. - Zoraxy widget missing on Homepage. Homepage v1.x has no built-in Zoraxy widget, but you can use the generic
customapiwidget against/api/stats/summaryto surface request counts. - AI gateway naming.
ai.nuclide.systemscurrently proxies LobeHub (a chat UI on:3210), while the LiteLLM API lives on:4000. For Nexa, point n8n directly at LiteLLM (http://192.168.1.40:4000over the docker net — no public TLS hop needed) to save latency and isolate from UI restarts. - MCP servers consolidation. Dozzle shows
crawl4ai-mcp,markitdown-mcp,papersearch-mcprunning individually. They're all MCP servers — Nexa Phase-3 could pull from these via LiteLLM's MCP support to enrich the embedding pipeline (e.g. fetch + markitdown a Karakeep link before embedding). - Backup the n8n SQLite file — Backrest covers
/home/node/.n8nif added; today the only "backup" is the workflow JSON which omits credentials and execution history. - Pocket-ID SSO in front of n8n would let you remove n8n basic-auth and unify session management across the whole stack. One-time setup, large UX win.
- Vaultwarden as the secret store for Nexa secrets (
SAIA_API_KEY,MEMOS_API_KEY, …) — read at bootstrap via the Bitwarden CLI from inside the docker host. Removes the need for a.envon disk. - AdGuard as DNS-based control plane. Since AdGuard is the resolver for the LAN, you can rewrite
*.nuclide.systemsto192.168.1.4(Zoraxy) internally and avoid a hairpin via the WAN — already the case if AdGuard rewrite rules are set, worth verifying. - Immich + Qdrant. Immich is already running and embeds photos with CLIP. If you ever want photo-aware Nexa answers, you can mount Immich's existing search via its API — no second embedding pass.
- Disk usage on LXC 104 is 47.7 % (Proxmox). Monitor; n8n execution logs and Dozzle history are the usual culprits. Setting
EXECUTIONS_DATA_PRUNE=trueandEXECUTIONS_DATA_MAX_AGE=168(7 days) on n8n keeps it bounded.