pbs-projects/Tech/Projects/ob1-main-deployment.md

11 KiB

project type status path tags created updated
ob1-main-deployment project-plan active Tech/Projects
homelab
ai
memory
ob1
supabase
mcp
docker
2026-05-04 2026-05-04

OB1 Deployment Project Plan

Deploy OpenBrain (OB1) as the personal AI memory layer on the homelab. OB1 is a self-hosted Postgres-plus-Supabase stack exposing MCP server access for any compatible AI client. This becomes the persistent memory layer underneath Claude Code Dispatch, Claude Desktop, and eventually Pi or other harnesses.

This plan is structured for hand-off to an agent after the OB1 repo is cloned. Each phase has explicit deliverables, validation steps, and stop conditions. The agent should pause after each phase for review before proceeding.

Background context the agent needs

  • OB1 source: github.com/NateBJones-Projects/OB1

  • Architecture: Supabase (Postgres + GoTrue + PostgREST + Kong + Studio + Edge Functions) with OB1's MCP server layered on top

  • Target deployment node: Proxmox VM on the existing homelab (assume a fresh Ubuntu 24.04 LTS VM unless directed otherwise)

  • Network: Tailscale mesh for remote access; Traefik already running on the homelab as the reverse proxy with HTTPS

  • Auth model: Authelia in front of web-facing surfaces (Studio UI); GoTrue stays for application identity and JWT issuance for AI clients

  • This is a personal single-user deployment initially. RLS policies should be in place but expect future expansion to a second user (Jenny) for shared PBS context

  • The user prefers Ansible for deployments and Docker Compose for service orchestration. UV for any Python work. Never use --break-system-packages

Phase 0 — Repository inspection and environment audit

Goal: understand what the agent is actually deploying before touching anything.

Tasks:

  • Read the OB1 README and any deployment or setup docs in the repo
  • Inventory the docker-compose.yml — list every service, its image, ports, volumes, dependencies
  • Identify which Supabase services OB1 actually requires versus which are bundled but unused (Realtime, Storage, ImgProxy, Logflare are likely candidates for disabling)
  • Check the OB1 MCP server implementation — language, runtime, dependencies, how it connects to Supabase
  • Note any environment variables, secrets, or external dependencies the deployment requires
  • Check schema or migration files — understand the data model before touching it

Deliverable: a written summary of what OB1 deploys, what's optional, what's required, and what external resources (API keys, URLs, secrets) the user needs to provide.

Stop condition: present the summary and the proposed Phase 1 plan to the user for review before proceeding.

Phase 1 — VM provisioning and base setup

Goal: clean Ubuntu 24.04 VM ready to run OB1.

Tasks:

  • Confirm with user: VM hostname, target Proxmox node, resource allocation (suggest 4 vCPU, 8GB RAM, 60GB disk as starting point — adjust based on Phase 0 findings)
  • Provision the VM via Proxmox (the user can do this manually; agent should provide exact specs)
  • Install Docker Engine and Docker Compose v2 (not the deprecated docker-compose v1)
  • Install Tailscale and join the mesh
  • Confirm Tailscale connectivity from the user's dev rig
  • Set up a non-root user for service operation (suggest ob1admin) with Docker group membership
  • Install basic operational tooling: htop, ncdu, git, curl, jq

Deliverable: a working VM accessible over Tailscale, with Docker installed and the OB1 repo cloned to /opt/ob1/ (or wherever the user prefers).

Stop condition: confirm with user that the VM is reachable and base setup is complete before proceeding to Phase 2.

Phase 2 — Trimmed Supabase deployment

Goal: get the Supabase stack running with only the services OB1 actually uses.

Tasks:

  • Based on Phase 0 inventory, modify docker-compose.yml to disable services OB1 doesn't require. Likely candidates for removal: Realtime, Storage, ImgProxy, Logflare, Vector
  • Generate strong secrets for: Postgres password, JWT secret, anon and service role keys, dashboard credentials. Use the Supabase secret generation pattern; do not reuse defaults
  • Configure Postgres with conservative resource settings: max_connections=20, shared_buffers=256MB. These can be tuned upward later if needed
  • Configure Kong's routing to only expose the services that remain
  • Bring up the stack with docker compose up -d and wait for all services to report healthy
  • Verify Postgres is reachable from inside the Docker network
  • Verify GoTrue is issuing tokens by creating a test user via the auth API
  • Verify PostgREST is serving the auto-generated REST API
  • Access Supabase Studio UI via Tailscale and confirm it loads

Deliverable: a running, trimmed Supabase stack on the VM. All services healthy. Studio UI reachable over Tailscale.

Stop condition: confirm with user that Supabase is up and Studio is accessible. Get approval before proceeding to Phase 3.

Phase 3 — OB1 schema and MCP server

Goal: deploy OB1's database schema and MCP server on top of the working Supabase stack.

Tasks:

  • Apply OB1's database migrations to Postgres — create the thoughts table, any related tables, RLS policies, indexes including the pgvector HNSW index
  • Configure OB1's MCP server with the Supabase connection details, JWT secret, and any API keys it needs (OpenAI for embeddings, or Ollama URL for local embeddings — user preference)
  • Decide with the user: cloud embeddings (OpenAI) for higher quality, or local embeddings (Ollama on the dev rig with the 3080) for zero cost and full data locality. Recommend local embeddings given user's homelab philosophy and existing Ollama setup
  • Run the MCP server (likely as a Docker container alongside Supabase, or as a systemd service depending on what OB1 ships)
  • Verify the MCP server starts cleanly and connects to Postgres
  • Test capture: insert a test thought via the MCP server's capture endpoint and verify it lands in the thoughts table with embedding and metadata populated
  • Test retrieval: query the MCP server's search endpoint and verify it returns the test thought via semantic search

Deliverable: OB1 MCP server running and operational. Test thought captured and retrievable.

Stop condition: confirm with user that capture and retrieval work end-to-end before proceeding.

Phase 4 — Authelia integration and Traefik routing

Goal: put OB1 behind the homelab's existing Authelia/Traefik perimeter.

Tasks:

  • Add Traefik labels (or update Traefik dynamic config) to route to:
    • Supabase Studio UI (Authelia-protected)
    • PostgREST API (Authelia-protected for direct access; bypassed for MCP server which uses JWTs)
    • GoTrue auth endpoints (no Authelia — these need to be reachable for JWT operations)
    • OB1 MCP server endpoint (no Authelia — clients use JWTs, not browser sessions)
  • Configure Authelia access control rules for the new routes
  • Verify HTTPS works for all exposed endpoints via Traefik
  • Test browser access to Studio: should hit Authelia login, then proceed to Studio
  • Test MCP server access: should bypass Authelia and authenticate via JWT only
  • Document the final URL map for the user

Deliverable: OB1 properly fronted by Traefik with Authelia gating browser surfaces. JWT-based clients reach the MCP server directly.

Stop condition: confirm full access pattern works from both browser (Authelia path) and AI client (JWT path).

Phase 5 — Client integration

Goal: connect Claude Code, Claude Desktop, and the existing n8n flows to OB1.

Tasks:

  • Generate a long-lived JWT or service-role API token for AI client use. Store in the user's KeePassXC database
  • Configure Claude Code's MCP integration to point at OB1's MCP server. Test capture and search from a Claude Code session
  • Configure Claude Desktop's MCP integration similarly. Test capture and search from a Desktop conversation
  • Add a node to the existing n8n markdown-summary intake flow that POSTs captured content to OB1's REST API in parallel with the existing Obsidian write. Map frontmatter fields to OB1 metadata
  • Test the full capture loop: send a test summary email through the existing flow and verify it lands in both Obsidian and OB1
  • Document the n8n flow modifications for the user

Deliverable: OB1 receiving captures from Claude Code, Claude Desktop, and the n8n email-intake pipeline. All three paths verified working.

Stop condition: confirm all three capture paths work and the user can perform an end-to-end test from any AI client.

Phase 6 — Operational hygiene

Goal: make the deployment maintainable.

Tasks:

  • Set up a daily Postgres backup via pg_dump to the Ubuntu NAS over Tailscale
  • Add the OB1 VM to existing monitoring (Uptime Kuma if it's monitoring infra services)
  • Document the deploy in an Ansible playbook so future re-provisioning is automated
  • Write a brief runbook covering: how to update OB1, how to restore from backup, how to rotate the JWT secret, how to add a new client
  • Snapshot the VM via Proxmox once everything is verified working

Deliverable: backups running, monitoring in place, Ansible playbook captures the deploy, runbook written, snapshot taken.

Stop condition: project complete. Hand off to user for ongoing use.

Out of scope

These are intentionally not part of this plan:

  • Building a custom technical-project extension for OB1 (separate project, after baseline is operational)
  • Adding Jenny as a second user with PBS-scoped access (separate project, after Jenny's content workflow lands)
  • Pre-compact hook for Dispatch transcript capture (separate project — needs design work on what to capture and how to filter noise)
  • Migrating existing Obsidian content into OB1 retroactively (separate project — bulk import path)

Agent operating instructions

  • Work one phase at a time. Stop and report at the end of each phase. Wait for user confirmation before proceeding to the next phase
  • For any ambiguous decision, ask the user rather than guessing
  • Never expose the homelab to the public internet during this deployment. Tailscale mesh is the only access path
  • All secrets generated during deployment go into the user's KeePassXC database. Never write them to disk in plaintext outside the running Docker environment
  • Use the user's preferred tooling: Docker Compose for orchestration, Ansible for repeatable deployment steps, UV for any Python work
  • If a step fails, do not retry blindly. Report the failure with the actual error output and propose next steps
  • The user prefers concise updates — report what was done, what's next, and any blockers. Skip the celebratory framing

-- ...sent from Jenny & Travis