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.
This commit is contained in:
214
docs/local-dev.md
Normal file
214
docs/local-dev.md
Normal file
@@ -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 <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
|
||||
```
|
||||
Reference in New Issue
Block a user