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)
| Task | Status | Details |
|---|---|---|
| Fork frappe_docker to dzinreach | DONE | Repo: dzinreach/frappe_docker (private). Custom files committed: compose.solanasis.yaml, build-custom-image.sh, apps.json, .env.example |
| Commit solanasis-docs untracked files | DONE | 7 planning/reference docs committed and pushed |
| Verify all other repos clean | DONE | solanasis_core, solanasis_crm, erpnext, frappe, sage-e — all clean |
Phase B: ERPNext API Setup (DONE)
| Task | Status | Details |
|---|---|---|
| Generate API key for claude-bot | DONE | Key generated via bench execute. Token auth verified working. |
| Set GitHub Secrets | DONE | ERPNEXT_URL, ERPNEXT_API_KEY, ERPNEXT_API_SECRET set on solanasis_crm, solanasis_core, solanasis-scripts |
| Create credential setup script | DONE | solanasis-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)
| Task | Status | Details |
|---|---|---|
| Deploy Baserow | DONE | Running on port 8880, image baserow/baserow:2.1.6, 4GB memory limit, 2GB actual usage |
| Docker Compose | DONE | At /home/zasage/_solanasis/baserow/docker-compose.yml |
| Data migration from cloud | DONE | 6 tables, 2,817 rows migrated (2026-03-24). Script: solanasis-scripts/scripts/migrate_cloud_to_selfhosted.py |
| Script URL updates | DONE | 8 Python + 2 TypeScript files now read BASEROW_BASE_URL from env |
| Workspace/DB rename | DONE | Workspace: “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):
| Table | Rows | Self-Hosted ID | Notes |
|---|---|---|---|
| Tag | 50 | 264 | Lookup table |
| Location | 32 | 265 | Lookup table |
| Organization | 72 | 266 | Links to Tag, Location |
| People | 179 | 267 | Links to Tag, Location, Organization |
| Meeting Notes | 38 | 272 | Links to People. Name field is text (convert to formula field('Person') in UI) |
| Foundation Prospects | 2446 | 271 | 5 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)
| Task | Status | Details |
|---|---|---|
| cloudflared updated | DONE | 2025.7.0 → 2026.3.0 |
| Authenticated with Solanasis account | DONE | cert.pem for solanasis.com zone |
| Tunnel created | DONE | Name: solanasis, ID: c57c4d9c-e408-4e43-b0d5-190baa70568e |
| config.yml written | DONE | Ingress: erp.solanasis.com (with httpHostHeader: db.solanasis.com), baserow.solanasis.com |
| DNS CNAME records created | DONE | erp.solanasis.com, baserow.solanasis.com → tunnel |
| systemd service updated | DONE | Runs tunnel run solanasis, added network-online.target dependency |
| End-to-end verification | DONE | ERPNext returns pong, Baserow returns 302 (setup redirect) |
| Old tunnels deleted | DONE | claude-bot and zasage_us_tunnel both deleted |
Key config decisions:
- Used
httpHostHeader: db.solanasis.comfor ERPNext ingress because Frappe identifies sites by Host header - Added
Wants=network-online.targetto 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.mdcredential-setup-guide.md
Cloudflare Account Details
| Account | ID | Zones | Usage |
|---|---|---|---|
| Solanasis | In GitHub Secrets: solanasis-site/CLOUDFLARE_ACCOUNT_ID | solanasis.com | Pages 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/...