Scaleway setup, k3s, kustomize structure, deployment phases, DNS, cert-manager, backup strategy, image registry.
7.1 KiB
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
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
# 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.
# 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
sedat deploy time
# 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
- Kubernetes & networking (k3s, Linkerd)
- Secrets (OpenBao, Vault Secrets Operator)
- Database (CloudNativePG)
- Cache (Valkey)
- Storage (SeaweedFS)
Phase 2 — Identity & Edge
- Ory Kratos & Hydra
- Pingora edge proxy
- cert-manager (Let's Encrypt)
Phase 3 — Applications
- Docs (Collabora)
- Meet (LiveKit)
- Drive
- Messages (full email stack)
- Calendars
- People
- Projects
- Find
- Integration navbar
Phase 4 — Connectivity & Sync
- Hive (Drive ↔ S3 sync)
- Postfix (outbound SMTP)
Phase 5 — Matrix & AI
- Tuwunel (Matrix homeserver)
- Sol☀️ (AI agent)
Phase 6 — Development Tools
- Gitea
- SearXNG
Phase 7 — Observability
- Prometheus + Grafana
- Loki + Alloy
- Tempo
- 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 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:
# 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. ✨