Files
customer-installer/CLAUDE.md
2026-03-01 20:12:52 +01:00

4.9 KiB
Raw Permalink Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Automates provisioning of customer Proxmox LXC containers running a Docker stack (n8n + PostgreSQL/pgvector + PostgREST) with automatic OPNsense NGINX reverse proxy registration. Intended for a multi-tenant SaaS setup ("BotKonzept") where each customer gets an isolated container.

Key Commands

# Create a new customer LXC (must run on Proxmox host)
bash install.sh --storage local-zfs --bridge vmbr0 --ip dhcp --vlan 90

# With debug output (logs on stderr instead of only to file)
DEBUG=1 bash install.sh --storage local-zfs --bridge vmbr0

# With APT caching proxy
bash install.sh --storage local-zfs --apt-proxy http://192.168.45.2:3142

# Setup the BotKonzept management LXC (fixed CTID 5010)
bash setup_botkonzept_lxc.sh

# Delete an nginx proxy entry in OPNsense
bash delete_nginx_proxy.sh --hostname sb-<unixts>

install.sh outputs a single JSON line to stdout with all credentials and URLs. Detailed logs go to logs/<hostname>.log. Credentials are saved to credentials/<hostname>.json.

Architecture

Script Dependency Tree

install.sh
├── sources libsupabase.sh          (Proxmox helpers, logging, crypto, n8n setup)
├── calls setup_nginx_proxy.sh      (OPNsense API integration)
└── uses lib_installer_json_api.sh  (PostgREST DB storage - optional)

setup_botkonzept_lxc.sh            (Standalone, for management LXC CTID 5010)

Infrastructure Assumptions (hardcoded defaults)

Service Address
OPNsense Firewall 192.168.45.1:4444
Apt-Cacher NG 192.168.45.2:3142
Docker Registry Mirror 192.168.45.2:5000
Ollama API 192.168.45.3:11434
Default VLAN 90
Default storage local-zfs
Default base domain userman.de

What install.sh Does (Steps 511)

  1. Step 5: Creates and starts Proxmox LXC (Debian 12), waits for DHCP IP
  2. Step 6: Installs Docker CE + Compose plugin inside the CT
  3. Step 7: Generates secrets (PG password, JWT, n8n encryption key), writes .env and docker-compose.yml into CT, starts the stack
  4. Step 8: Creates n8n owner account via REST API
  5. Step 10: Imports and activates the RAG workflow via n8n API, sets up credentials (Postgres + Ollama)
  6. Step 10a: Installs a systemd service (n8n-workflow-reload.service) that re-imports and re-activates the workflow on every LXC restart
  7. Step 11: Registers an NGINX upstream/location in OPNsense via its REST API

Docker Stack Inside Each LXC (/opt/customer-stack/)

  • postgres pgvector/pgvector:pg16, initialized from sql/ directory
  • postgrest PostgREST, exposes Supabase-compatible REST API on port 3000 (mapped to POSTGREST_PORT)
  • n8n n8n automation, port 5678

All three share a customer-net bridge network. The n8n instance connects to PostgREST via the Docker internal hostname postgrest:3000 (not the external IP).

Key Files

File Purpose
libsupabase.sh Core library: logging (info/warn/die), Proxmox helpers (pct_exec, pct_push_text, pve_*), crypto (gen_password_policy, gen_hex_64), n8n setup (n8n_setup_rag_workflow)
setup_nginx_proxy.sh OPNsense API client; registers upstream + location for new CT
lib_installer_json_api.sh Stores installer JSON output into the BotKonzept Postgres DB via PostgREST
sql/botkonzept_schema.sql Customer management schema (customers, instances, emails, payments) for the BotKonzept management LXC
sql/init_pgvector.sql Inline in install.sh; creates pgvector extension, documents table, match_documents function, PostgREST roles
templates/reload-workflow.sh Runs inside customer LXC on every restart; logs to /opt/customer-stack/logs/workflow-reload.log
RAGKI-BotPGVector.json Default n8n workflow template (RAG KI-Bot with PGVector)

Output and Logging

  • Normal mode (DEBUG=0): all script output goes to logs/<hostname>.log; only the final JSON is printed to stdout (via fd 3)
  • Debug mode (DEBUG=1): logs also written to stderr; JSON is formatted with python3 -m json.tool
  • Each customer container hostname is sb-<unix_timestamp>; CTID = unix_timestamp 1,000,000,000

n8n Password Policy

Passwords must be 8+ characters with at least 1 uppercase and 1 number. Enforced by password_policy_check in libsupabase.sh. Auto-generated passwords use gen_password_policy.

Workflow Auto-Reload

On LXC restart, n8n-workflow-reload.service runs reload-workflow.sh, which:

  1. Waits for n8n API to be ready (up to 60s)
  2. Logs in with owner credentials from .env
  3. Deletes the existing "RAG KI-Bot (PGVector)" workflow
  4. Looks up existing Postgres and Ollama credential IDs
  5. Processes the workflow template (replaces credential IDs using Python)
  6. Imports and activates the new workflow