docs: add production deployment guide — Serving Looks in Production 👠
Scaleway setup, k3s, kustomize structure, deployment phases, DNS, cert-manager, backup strategy, image registry.
This commit is contained in:
258
docs/deployment.md
Normal file
258
docs/deployment.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# Serving Looks in Production 👠
|
||||
|
||||
The Super Boujee Business Box ✨ runs on a single Scaleway Elastic Metal server in Paris. One box, one bill, European data sovereignty by default. No multi-cloud, no multi-region, no per-seat fees — just a server that belongs to you.
|
||||
|
||||
---
|
||||
|
||||
## The Server
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Provider** | Scaleway Elastic Metal |
|
||||
| **Region** | Paris (PAR1/PAR2) |
|
||||
| **RAM** | 64GB minimum |
|
||||
| **Storage** | Local NVMe |
|
||||
| **Network** | Public IPv4, configurable reverse DNS |
|
||||
| **Monthly cost** | ~€50–80 (server) + ~€7–16 (services) |
|
||||
|
||||
### External Scaleway Services
|
||||
|
||||
| Service | Purpose | Cost |
|
||||
|---------|---------|------|
|
||||
| Object Storage | PostgreSQL backups (barman), cold asset overflow | ~€5–10/mo |
|
||||
| Transactional Email (TEM) | Outbound SMTP relay | ~€1/mo |
|
||||
| Generative APIs | AI inference for all components | ~€1–5/mo |
|
||||
|
||||
Total: under €100/month for the entire collaboration suite. That's less than three Slack seats. 💅
|
||||
|
||||
---
|
||||
|
||||
## k3s Installation
|
||||
|
||||
```bash
|
||||
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik" sh -
|
||||
```
|
||||
|
||||
Traefik is disabled because we use Pingora. k3s gives us single-binary Kubernetes without the overhead of a full cluster setup.
|
||||
|
||||
---
|
||||
|
||||
## Deployment Flow
|
||||
|
||||
### First-Time Setup
|
||||
|
||||
```bash
|
||||
# 1. Install k3s (above)
|
||||
|
||||
# 2. Configure sunbeam
|
||||
sunbeam config set \
|
||||
--domain sunbeam.pt \
|
||||
--host admin@{SERVER_IP} \
|
||||
--infra-dir /path/to/sbbb \
|
||||
--acme-email ops@sunbeam.pt
|
||||
|
||||
# 3. Bring up core infrastructure
|
||||
sunbeam up # cert-manager, Linkerd, TLS
|
||||
|
||||
# 4. Deploy everything
|
||||
sunbeam apply # all namespaces
|
||||
|
||||
# 5. Seed credentials
|
||||
sunbeam seed # all secrets into OpenBao
|
||||
|
||||
# 6. Bootstrap services
|
||||
sunbeam bootstrap # Gitea orgs, repos, service accounts
|
||||
|
||||
# 7. Verify
|
||||
sunbeam verify # OpenBao + VSO sync test
|
||||
sunbeam check # functional health probes
|
||||
```
|
||||
|
||||
### Ongoing Deployments
|
||||
|
||||
The daily driver. Most deploys are just one command.
|
||||
|
||||
```bash
|
||||
# Deploy all namespaces
|
||||
sunbeam apply
|
||||
|
||||
# Deploy specific namespace
|
||||
sunbeam apply lasuite
|
||||
sunbeam apply monitoring
|
||||
sunbeam apply matrix
|
||||
|
||||
# Build, push, and deploy a service
|
||||
sunbeam build sol --push --deploy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Kustomize Structure
|
||||
|
||||
```
|
||||
sbbb/
|
||||
├── base/ # Canonical manifests (environment-agnostic)
|
||||
│ ├── data/ # PostgreSQL, Valkey, OpenSearch, OpenBao, SearXNG
|
||||
│ ├── devtools/ # Gitea
|
||||
│ ├── ingress/ # Pingora proxy
|
||||
│ ├── lasuite/ # All La Suite apps + Hive + Postfix
|
||||
│ ├── matrix/ # Tuwunel + Sol☀️
|
||||
│ ├── media/ # LiveKit
|
||||
│ ├── mesh/ # Linkerd
|
||||
│ ├── monitoring/ # Prometheus, Grafana, Loki, Tempo, Alloy
|
||||
│ ├── ory/ # Kratos + Hydra
|
||||
│ ├── storage/ # SeaweedFS
|
||||
│ ├── cert-manager/ # Certificate management
|
||||
│ ├── longhorn/ # Volume management
|
||||
│ └── vso/ # Vault Secrets Operator
|
||||
├── overlays/
|
||||
│ ├── local/ # Local dev patches (resource limits, mkcert)
|
||||
│ └── production/ # Production patches (SSL, full resources)
|
||||
├── scripts/ # Bash automation
|
||||
└── docs/ # You are here ✨
|
||||
```
|
||||
|
||||
### The Pattern
|
||||
|
||||
- **Base** holds canonical config — deployments, services, configmaps, values files, vault secrets, alert rules, service monitors
|
||||
- **Overlays** hold only patches — resource overrides, domain-specific values, environment differences
|
||||
- **DOMAIN_SUFFIX** placeholder gets replaced by `sed` at deploy time
|
||||
|
||||
```bash
|
||||
# What sunbeam apply does under the hood
|
||||
kustomize build overlays/production \
|
||||
| sed 's/DOMAIN_SUFFIX/sunbeam.pt/g' \
|
||||
| kubectl apply --server-side -f -
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deployment Phases
|
||||
|
||||
The stack deploys in order of dependency — foundation first, glamour later:
|
||||
|
||||
### Phase 1 — Core Infrastructure
|
||||
1. Kubernetes & networking (k3s, Linkerd)
|
||||
2. Secrets (OpenBao, Vault Secrets Operator)
|
||||
3. Database (CloudNativePG)
|
||||
4. Cache (Valkey)
|
||||
5. Storage (SeaweedFS)
|
||||
|
||||
### Phase 2 — Identity & Edge
|
||||
6. Ory Kratos & Hydra
|
||||
7. Pingora edge proxy
|
||||
8. cert-manager (Let's Encrypt)
|
||||
|
||||
### Phase 3 — Applications
|
||||
9. Docs (Collabora)
|
||||
10. Meet (LiveKit)
|
||||
11. Drive
|
||||
12. Messages (full email stack)
|
||||
13. Calendars
|
||||
14. People
|
||||
15. Projects
|
||||
16. Find
|
||||
17. Integration navbar
|
||||
|
||||
### Phase 4 — Connectivity & Sync
|
||||
18. Hive (Drive ↔ S3 sync)
|
||||
19. Postfix (outbound SMTP)
|
||||
|
||||
### Phase 5 — Matrix & AI
|
||||
20. Tuwunel (Matrix homeserver)
|
||||
21. Sol☀️ (AI agent)
|
||||
|
||||
### Phase 6 — Development Tools
|
||||
22. Gitea
|
||||
23. SearXNG
|
||||
|
||||
### Phase 7 — Observability
|
||||
24. Prometheus + Grafana
|
||||
25. Loki + Alloy
|
||||
26. Tempo
|
||||
27. AlertManager
|
||||
|
||||
---
|
||||
|
||||
## DNS Setup
|
||||
|
||||
All subdomains point to the server's public IP via A records:
|
||||
|
||||
```
|
||||
docs.sunbeam.pt → A → {SERVER_IP}
|
||||
meet.sunbeam.pt → A → {SERVER_IP}
|
||||
drive.sunbeam.pt → A → {SERVER_IP}
|
||||
mail.sunbeam.pt → A → {SERVER_IP}
|
||||
messages.sunbeam.pt → A → {SERVER_IP}
|
||||
people.sunbeam.pt → A → {SERVER_IP}
|
||||
src.sunbeam.pt → A → {SERVER_IP}
|
||||
auth.sunbeam.pt → A → {SERVER_IP}
|
||||
cal.sunbeam.pt → A → {SERVER_IP}
|
||||
projects.sunbeam.pt → A → {SERVER_IP}
|
||||
metrics.sunbeam.pt → A → {SERVER_IP}
|
||||
livekit.sunbeam.pt → A → {SERVER_IP}
|
||||
s3.sunbeam.pt → A → {SERVER_IP}
|
||||
# ... and the rest
|
||||
```
|
||||
|
||||
### Email DNS
|
||||
|
||||
Email requires additional records:
|
||||
|
||||
| Record | Value |
|
||||
|--------|-------|
|
||||
| **MX** | Points to server IP (messages-mta-in listens on port 25) |
|
||||
| **SPF** | `v=spf1 ip4:{SERVER_IP} include:tem.scaleway.com ~all` |
|
||||
| **DKIM** | Generated by Postfix/Rspamd, published as TXT record |
|
||||
| **DMARC** | `v=DMARC1; p=quarantine; rua=mailto:dmarc@sunbeam.pt` |
|
||||
| **PTR** | Reverse DNS configured in Scaleway console |
|
||||
|
||||
---
|
||||
|
||||
## TLS Certificates
|
||||
|
||||
cert-manager handles Let's Encrypt certificates in production:
|
||||
|
||||
- ACME HTTP-01 challenges routed by Pingora itself (watches Ingress objects for solver pods)
|
||||
- Certificates stored in K8s Secret `pingora-tls`
|
||||
- Pingora watches the Secret and hot-reloads on renewal (zero downtime)
|
||||
|
||||
---
|
||||
|
||||
## Backups
|
||||
|
||||
### PostgreSQL
|
||||
|
||||
- **Tool:** barman (continuous archiving)
|
||||
- **Destination:** Scaleway Object Storage
|
||||
- **Retention:** 30 days (see [ops.md](ops.md) for the 7-year cold storage gap)
|
||||
- **Recovery:** CloudNativePG handles point-in-time recovery
|
||||
|
||||
### Secrets
|
||||
|
||||
- OpenBao (Vault) data backed up separately
|
||||
- Root token and unseal keys stored securely offline
|
||||
|
||||
### Object Storage
|
||||
|
||||
- SeaweedFS volumes on local NVMe
|
||||
- Game assets also exist in Drive (Hive keeps them synced — bless that fairy)
|
||||
- Consider periodic snapshots for critical buckets
|
||||
|
||||
---
|
||||
|
||||
## Image Registry
|
||||
|
||||
Container images are built and stored in the Gitea registry at `src.sunbeam.pt`:
|
||||
|
||||
```bash
|
||||
# Build and push
|
||||
sunbeam build proxy --push
|
||||
sunbeam build sol --push
|
||||
|
||||
# Images tagged as
|
||||
src.sunbeam.pt/studio/proxy:latest
|
||||
src.sunbeam.pt/studio/sol:latest
|
||||
```
|
||||
|
||||
For arm64 targets, `sunbeam mirror` rebuilds amd64-only La Suite images for multi-arch support. We don't discriminate against architectures. ✨
|
||||
Reference in New Issue
Block a user