Self-Hosted CRM and Operational Stack for Solopreneurs
Overview
- Project: Self-Hosted Tool Stack
- Status: Active — CRM selection in progress
- Context: Consulting solopreneur, not B2B product sales
CRM Assessment for Consulting
| Option | Verdict | Rationale |
|---|---|---|
| EspoCRM | Best fit | API-friendly, custom entities for “Projects”/“Consultations”, service-oriented |
| Krayin | Acceptable | Laravel/lightweight, but designed for products — requires “productizing” services |
| InvoiceNinja | Hidden gem | Client Manager + Invoicing in one — often replaces CRM entirely for consultants |
| Twenty | Overkill | Salesforce alternative; too heavy for solopreneur consulting |
| Frappe CRM | Overkill | Rarely used alone; designed for ERPNext ecosystem |
| Monica | Rejected | Personal relationship manager, not for business workflows |
Adopted Stack Architecture
Three Layers
-
Client Data (Source of Truth)
- EspoCRM: conversations, meeting notes, contract dates
- InvoiceNinja: tax IDs, billing address, payment status
-
Execution (The Work)
- Plane: project delivery, tasks, sprints
- Peppermint: external client requests and issues
-
Ledger (The Result)
- Firefly III: operational costs, subscriptions
Integration via Quartz.NET + C#
No middleware (n8n rejected). Custom Quartz.NET jobs using Dapper (fast reads) and HttpClient (safe writes), with AHK for desktop UI triggers.
Key Workflows
New Client Handshake (EspoCRM to InvoiceNinja)
Lead converted in EspoCRM → Quartz job polls API → creates client in InvoiceNinja → writes invoice_ninja_client_id back to EspoCRM.
Support-to-Project Pipeline
Peppermint ticket tagged #escalate → Quartz job detects → creates Plane issue → replies to ticket with reference.
Revenue Recognition (Get Paid Loop)
InvoiceNinja receives payment → Quartz job formats transaction → POSTs deposit to Firefly III.
Implementation Pitfalls
| Pitfall | Risk | Fix |
|---|---|---|
| Firefly as business tool | Can’t generate invoices | Use for expense ledger only; InvoiceNinja for billing |
| Ghost Peppermint users | Untracked clients create tickets | Nightly script checks for unknown emails |
| InvoiceNinja URL changes | Client portal links break | Set final domain before first use |
| Backup corruption | Copying raw DB folders while running | Use pg_dump/mysqldump inside containers first |
Docker Best Practices
- Create shared
solonetDocker network for inter-container communication - Keep Postgres (Plane/Peppermint) and MySQL (Espo/InvoiceNinja) databases separate
- Use Traefik or Nginx Proxy Manager for SSL and routing
- Plan for SSO (Authentik/Keycloak) even if not implemented immediately
Related
- firefly-iii-evaluation — Finance tool deep evaluation
- plane-project-management-evaluation — Project management evaluation