From 265a68d85f2a76a4e750bf4eb799fcd07e33984e Mon Sep 17 00:00:00 2001 From: Sienna Meridian Satterwhite Date: Tue, 24 Mar 2026 11:46:40 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20add=20local=20dev=20setup=20guide=20?= =?UTF-8?q?=E2=80=94=20Setting=20Up=20Your=20Vanity=20=F0=9F=92=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lima VM, k3s, mkcert, sslip.io, sunbeam CLI setup, resource budget, differences from production, common commands, troubleshooting. --- docs/local-dev.md | 214 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 docs/local-dev.md diff --git a/docs/local-dev.md b/docs/local-dev.md new file mode 100644 index 0000000..8e8bc51 --- /dev/null +++ b/docs/local-dev.md @@ -0,0 +1,214 @@ +# Setting Up Your Vanity 💄 + +Local development for The Super Boujee Business Box ✨ runs on a Lima VM with k3s. The whole stack — every app, every service — runs on your laptop. It's the same architecture as production, just with smaller resource limits and self-signed TLS. + +--- + +## Prerequisites + +- macOS (Apple Silicon or Intel) +- [Lima](https://lima-vm.io/) — lightweight Linux VMs on Apple Virtualization.framework +- [mkcert](https://github.com/FiloSottile/mkcert) — local TLS certificates +- [Sunbeam CLI](cli.md) — the remote control + +```bash +brew install lima mkcert +``` + +And install sunbeam: +```bash +git clone https://src.sunbeam.pt/studio/cli.git +cd cli && cargo install --path sunbeam +``` + +--- + +## Create the VM + +```bash +limactl start --name=sunbeam --memory=12 --cpus=6 --disk=60 template://k3s +``` + +This gives you a k3s cluster inside a Lima VM with: +- 12GB RAM (enough for the full stack) +- 6 CPUs +- 60GB disk + +Lima uses Apple's Virtualization.framework — native performance, no emulation overhead. + +--- + +## Configure Sunbeam + +Get the Lima VM IP and set up your context: + +```bash +LIMA_IP=$(limactl shell sunbeam -- hostname -I | awk '{print $1}') + +sunbeam config set \ + --domain "${LIMA_IP}.sslip.io" \ + --infra-dir /path/to/sbbb \ + --acme-email dev@localhost +``` + +### sslip.io DNS + +No DNS configuration needed. [sslip.io](https://sslip.io) provides wildcard DNS resolution — any subdomain of `{IP}.sslip.io` resolves to that IP: + +``` +docs.192.168.5.2.sslip.io → 192.168.5.2 +meet.192.168.5.2.sslip.io → 192.168.5.2 +src.192.168.5.2.sslip.io → 192.168.5.2 +``` + +Every app just works. + +--- + +## TLS with mkcert + +Generate a wildcard certificate for your local domain: + +```bash +mkcert "*.${LIMA_IP}.sslip.io" +``` + +This creates `_wildcard.{IP}.sslip.io.pem` + `_wildcard.{IP}.sslip.io-key.pem`. The sunbeam CLI handles mounting these into the cluster as a K8s Secret for Pingora. + +mkcert's root CA is already trusted by your system — no browser warnings. + +--- + +## Bring Up the Cluster + +```bash +# Install cert-manager, Linkerd, TLS +sunbeam up + +# Deploy everything +sunbeam apply + +# Seed all credentials in OpenBao +sunbeam seed + +# Bootstrap Gitea orgs and repos +sunbeam bootstrap +``` + +That's it. Go get a coffee — or a mimosa, we don't judge. When you come back: + +```bash +sunbeam status # check everything's running +sunbeam check # functional health probes +``` + +--- + +## Access Your Stack + +Open in your browser: + +| App | URL | +|-----|-----| +| Docs | `https://docs.{LIMA_IP}.sslip.io` | +| Drive | `https://drive.{LIMA_IP}.sslip.io` | +| Mail | `https://mail.{LIMA_IP}.sslip.io` | +| Messages (Matrix) | `https://messages.{LIMA_IP}.sslip.io` | +| Meet | `https://meet.{LIMA_IP}.sslip.io` | +| Calendar | `https://cal.{LIMA_IP}.sslip.io` | +| Projects | `https://projects.{LIMA_IP}.sslip.io` | +| Gitea | `https://src.{LIMA_IP}.sslip.io` | +| Grafana | `https://metrics.{LIMA_IP}.sslip.io` | +| Auth | `https://auth.{LIMA_IP}.sslip.io` | + +--- + +## Resource Budget + +Target: ~5.5–6GB total for pods, plus OS overhead. + +| Component | Memory | +|-----------|--------| +| Linkerd (control + 20 sidecars) | ~300MB | +| PostgreSQL | 512MB | +| Valkey | 64MB | +| OpenSearch | 512MB | +| SeaweedFS (master + volume + filer) | ~576MB | +| Ory (Kratos + Hydra) | ~128MB | +| La Suite apps (7 × ~256MB) | ~1.8GB | +| Gitea | 256MB | +| Sol☀️ | 256–512MB | +| Hive | 64MB | +| Pingora | 256MB | +| Monitoring (Prometheus + Grafana + Loki + Tempo + Alloy) | ~1GB | + +12GB VM gives comfortable headroom. + +--- + +## Differences from Production + +| Aspect | Production | Local | +|--------|-----------|-------| +| Domain | `sunbeam.pt` | `{LIMA_IP}.sslip.io` | +| TLS | cert-manager + Let's Encrypt | mkcert self-signed wildcard | +| Server | 64GB Scaleway Elastic Metal | 12GB Lima VM | +| Backups | barman → Scaleway Object Storage | Disabled | +| Email DNS | MX, SPF, DKIM, DMARC, PTR | N/A (no inbound email) | +| Email relay | Scaleway TEM | Local Postfix (or disabled) | + +The stack is architecturally identical — same manifests, same overlays, just different resource limits and TLS. + +--- + +## Common Commands + +```bash +# Rebuild and deploy a service +sunbeam build sol --push --deploy + +# Watch logs +sunbeam logs matrix/sol -f + +# Restart something that's misbehaving +sunbeam restart lasuite/drive + +# Apply changes to just one namespace +sunbeam apply lasuite + +# Check service health +sunbeam check + +# Access raw kubectl +sunbeam k8s get pods -A +``` + +--- + +## Troubleshooting + +**Pod stuck in CrashLoopBackOff:** +```bash +sunbeam logs {namespace}/{service} # check the logs +sunbeam restart {namespace}/{service} # try a restart +``` + +**Database connection errors:** +```bash +sunbeam check data # check PostgreSQL health +sunbeam vault status # is OpenBao sealed? +sunbeam vault unseal # unseal if needed +``` + +**TLS certificate errors:** +```bash +# Regenerate mkcert certs +mkcert "*.${LIMA_IP}.sslip.io" +sunbeam apply ingress # redeploy with new cert +``` + +**Everything's broken (we've all been there):** +```bash +sunbeam status # what's actually running? +sunbeam mon loki logs '{namespace="monitoring"}' # check the watchers +```