Foundation — System Architecture
Approach 2: Standard foundation with ops shell. Sub-project 0 of 4.
Containers on the VPS (marketing-campaign compose project)
┌──────────────────────────┐
│ Internet (Cloudflare) │
│ marketing.daniel...dev │
└────────────┬─────────────┘
│ HTTPS (Let's Encrypt)
▼
┌──────────────────┐
│ CADDY │ ports 80/443
│ (gateway) │ routes / → web
│ already up ✓ │ routes /api → api
└────┬─────────────┘
│
┌──────────────────┴──────────────────┐
▼ ▼
┌───────────────────┐ ┌──────────────────────┐
│ WEB (Vite) │ │ API (Fastify) │
│ nginx :80 │ ←OIDC │ cluster mode :3000 │
│ serves SPA │ redirect │ 3 workers │
│ ~80MB │ │ limits: 1.5GB/3CPU │
│ │ │ │
│ left-sidebar UI: │ │ /api/auth/* OIDC │
│ • Dashboard │ │ /api/creds/* CRUD │
│ • Credentials │ │ /api/projects/* │
│ • Projects │ │ /api/audit/* │
│ • ETL (placehold)│ │ /api/health │
│ • Recos (placeh) │ │ │
│ • Collect (plac) │ └────┬───────────┬─────┘
│ • Audit │ │ │
│ • Users │ ▼ ▼
└───────────────────┘ ┌──────────────┐ ┌──────────────┐
│ POSTGRES │ │ REDIS │
│ :5432 │ │ :6379 │
│ own volume │ │ shared with │
│ ~80MB │ │ existing │
│ │ │ deploy-redis│
│ • users │ │ │
│ • sessions │ │ • sessions │
│ • creds 🔒 │ │ (7-day │
│ • projects │ │ TTL) │
│ • audit_log │ │ • cache:* │
│ • runs │ │ (later) │
└──────────────┘ └──────────────┘
┌───────────────────────────────────────────────────────────────┐
│ TELEMETRY (existing vps-monitoring stack — we just emit) │
│ pino JSON → stdout → promtail → loki → grafana │
│ prom metrics on :3000/metrics → vps-monitoring-prometheus │
│ (we add scrape config; no new containers) │
└───────────────────────────────────────────────────────────────┘
resource budget on this 4 vCPU / ~4 GB-free VPS:
┌─────────────┬─────────┬──────────┬───────────────────────────┐
│ service │ RAM cap │ CPU cap │ rationale │
├─────────────┼─────────┼──────────┼───────────────────────────┤
│ caddy │ 128 MB │ 0.5 │ stateless, lightweight │
│ api │ 1.5 GB │ 3.0 │ cluster (3 workers) │
│ web (nginx) │ 80 MB │ 0.5 │ static SPA serve │
│ postgres │ 512 MB │ 1.0 │ small dataset, conn pool │
│ TOTAL │ ~2.2GB │ ~5 │ fits comfortably │
└─────────────┴─────────┴──────────┴───────────────────────────┘
Approve in the terminal — next we walk through components, data flow, security.