Files
sbbb/docs/local-dev.md
Sienna Meridian Satterwhite 265a68d85f docs: add local dev setup guide — Setting Up Your Vanity 💄
Lima VM, k3s, mkcert, sslip.io, sunbeam CLI setup, resource budget,
differences from production, common commands, troubleshooting.
2026-03-24 11:46:40 +00:00

215 lines
5.1 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.56GB 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☀ | 256512MB |
| 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 <key> # 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
```