Solanasis Infrastructure Setup Plan

Date: 2026-03-22 (started), 2026-03-23 (completed) Status: Complete All phases done. Infrastructure is fully operational.


Overview

This plan covers getting all Solanasis infrastructure version-controlled, API-accessible, and multi-service routed via Cloudflare tunnels. It was designed with senior review and validated assumptions.


What’s Been Completed

Phase A: Git Sync (DONE)

TaskStatusDetails
Fork frappe_docker to dzinreachDONERepo: dzinreach/frappe_docker (private). Custom files committed: compose.solanasis.yaml, build-custom-image.sh, apps.json, .env.example
Commit solanasis-docs untracked filesDONE7 planning/reference docs committed and pushed
Verify all other repos cleanDONEsolanasis_core, solanasis_crm, erpnext, frappe, sage-e — all clean

Phase B: ERPNext API Setup (DONE)

TaskStatusDetails
Generate API key for claude-botDONEKey generated via bench execute. Token auth verified working.
Set GitHub SecretsDONEERPNEXT_URL, ERPNEXT_API_KEY, ERPNEXT_API_SECRET set on solanasis_crm, solanasis_core, solanasis-scripts
Create credential setup scriptDONEsolanasis-scripts/scripts/setup_erpnext_env.py — sets up ~/.config/solanasis/.env on new machines

ERPNext API access pattern:

curl -H "Authorization: token $ERPNEXT_API_KEY:$ERPNEXT_API_SECRET" \
  https://erp.solanasis.com/api/method/frappe.auth.get_logged_user
# Returns: {"message": "claude-bot@solanasis.com"}

Phase D: Baserow Self-Hosted (DONE)

TaskStatusDetails
Deploy BaserowDONERunning on port 8880, image baserow/baserow:2.1.6, 4GB memory limit, 2GB actual usage
Docker ComposeDONEAt /home/zasage/_solanasis/baserow/docker-compose.yml
Data migration from cloudDONE6 tables, 2,817 rows migrated (2026-03-24). Script: solanasis-scripts/scripts/migrate_cloud_to_selfhosted.py
Script URL updatesDONE8 Python + 2 TypeScript files now read BASEROW_BASE_URL from env
Workspace/DB renameDONEWorkspace: “Solanasis”, Database: “Solanasis CRM”

Baserow access: https://baserow.solanasis.com (via Cloudflare Tunnel, ACTIVE) Admin: ds@solanasis.com (created 2026-03-24) API Token: claude-bot — DB token with full CRUD permissions (created 2026-03-24) Database: “Solanasis CRM” (ID: 54), Workspace: “Solanasis” (ID: 45)

Migrated tables (2026-03-24):

TableRowsSelf-Hosted IDNotes
Tag50264Lookup table
Location32265Lookup table
Organization72266Links to Tag, Location
People179267Links to Tag, Location, Organization
Meeting Notes38272Links to People. Name field is text (convert to formula field('Person') in UI)
Foundation Prospects24462715 single_select fields, no link_row

Not migrated (out of scope): fCTO Partners, MSP Prospects — never existed on cloud. Need full pipeline re-run.


Completed

Phase C: Cloudflare Tunnel Setup (DONE — 2026-03-23)

TaskStatusDetails
cloudflared updatedDONE2025.7.0 → 2026.3.0
Authenticated with Solanasis accountDONEcert.pem for solanasis.com zone
Tunnel createdDONEName: solanasis, ID: c57c4d9c-e408-4e43-b0d5-190baa70568e
config.yml writtenDONEIngress: erp.solanasis.com (with httpHostHeader: db.solanasis.com), baserow.solanasis.com
DNS CNAME records createdDONEerp.solanasis.com, baserow.solanasis.com → tunnel
systemd service updatedDONERuns tunnel run solanasis, added network-online.target dependency
End-to-end verificationDONEERPNext returns pong, Baserow returns 302 (setup redirect)
Old tunnels deletedDONEclaude-bot and zasage_us_tunnel both deleted

Key config decisions:

  • Used httpHostHeader: db.solanasis.com for ERPNext ingress because Frappe identifies sites by Host header
  • Added Wants=network-online.target to systemd service for WSL2 reliability
  • Locally-managed tunnel (config-as-code) rather than dashboard-managed

Phase E: Documentation (DONE — 2026-03-23)

Operations docs committed to solanasis-docs/operations/:

  • infrastructure-setup-plan.md (this file)
  • service-inventory.md
  • credential-setup-guide.md

Cloudflare Account Details

AccountIDZonesUsage
SolanasisIn GitHub Secrets: solanasis-site/CLOUDFLARE_ACCOUNT_IDsolanasis.comPages deployment + tunnel (solanasis)

Tunnel auth: Uses cert.pem from cloudflared login (Option C). The cert.pem is scoped to the solanasis.com zone and lives at ~/.cloudflared/cert.pem.

Note: The old Matchkeyz account (Admin@matchkeyz.com, zone zasage.us) tunnels (claude-bot, zasage_us_tunnel) were deleted on 2026-03-23.


Architecture Diagram

Internet
    │
    ▼
Cloudflare Edge (solanasis.com zone)
    │
    ├── erp.solanasis.com ──── Cloudflare Tunnel ──── localhost:8080 (ERPNext)
    ├── baserow.solanasis.com ── Cloudflare Tunnel ──── localhost:8880 (Baserow)
    └── solanasis.com ────────── Cloudflare Pages ────── (static site)

WSL2 Server (this machine)
    ├── ERPNext Docker Stack (9 containers)
    │   ├── Frontend/Nginx :8080
    │   ├── Backend (Frappe API)
    │   ├── MariaDB :3306
    │   ├── Redis Cache/Queue :6379
    │   ├── Workers (short/long queue)
    │   ├── Scheduler
    │   └── WebSocket :9000
    ├── Baserow :8880 (all-in-one: PostgreSQL, Redis, Celery, Caddy)
    ├── Neo4j :7474/7687
    ├── Qdrant :6333
    ├── Milvus :2379/19530
    ├── OpenMemory MCP :8765
    ├── Graphiti MCP :8800
    └── LiteLLM :4000

Second WSL Machine (Claude Code)
    └── Uses $ERPNEXT_API_KEY:$ERPNEXT_API_SECRET
        to access https://erp.solanasis.com/api/...