chore: initial infrastructure scaffold

Kustomize base + overlays for the full Sunbeam k3s stack:
- base/mesh      — Linkerd edge (crds + control-plane + viz)
- base/ingress   — custom Pingora edge proxy
- base/ory       — Kratos 0.60.1 + Hydra 0.60.1 + login-ui
- base/data      — CloudNativePG 0.27.1, Valkey 8, OpenSearch 2
- base/storage   — SeaweedFS master + volume + filer (S3 on :8333)
- base/lasuite   — Hive sync daemon + La Suite app placeholders
- base/media     — LiveKit livekit-server 1.9.0
- base/devtools  — Gitea 12.5.0 (external PG + Valkey)
overlays/local   — sslip.io domain, mkcert TLS, Lima hostPort
overlays/production — stub (TODOs for sunbeam.pt values)
scripts/         — local-up/down/certs/urls helpers
justfile         — up / down / certs / urls targets
This commit is contained in:
2026-02-28 13:42:27 +00:00
commit 5d9bd7b067
51 changed files with 2647 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: ingress
resources:
- namespace.yaml
- pingora-deployment.yaml
- pingora-service.yaml
- pingora-config.yaml

View File

@@ -0,0 +1,5 @@
apiVersion: v1
kind: Namespace
metadata:
name: ingress
# Linkerd annotation intentionally omitted — Pingora is the mesh ingress gateway

View File

@@ -0,0 +1,70 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: pingora-config
namespace: ingress
data:
config.toml: |
# Pingora hostname routing table
# The domain suffix (sunbeam.pt / <LIMA_IP>.sslip.io) is patched per overlay.
# TLS cert source (rustls-acme / mkcert) is patched per overlay.
[tls]
cert_path = "/etc/tls/tls.crt"
key_path = "/etc/tls/tls.key"
# acme = true # Uncommented in production overlay (rustls-acme + Let's Encrypt)
acme = false
[listen]
http = "0.0.0.0:80"
https = "0.0.0.0:443"
[turn]
backend = "livekit.media.svc.cluster.local:7880"
udp_listen = "0.0.0.0:3478"
relay_port_start = 49152
relay_port_end = 49252
# Host-prefix → backend mapping.
# Pingora matches on the subdomain prefix regardless of domain suffix,
# so these routes work identically for sunbeam.pt and *.sslip.io.
[[routes]]
host_prefix = "docs"
backend = "http://docs.lasuite.svc.cluster.local:8000"
websocket = true # Y.js CRDT sync
[[routes]]
host_prefix = "meet"
backend = "http://meet.lasuite.svc.cluster.local:8000"
websocket = true # LiveKit signaling
[[routes]]
host_prefix = "drive"
backend = "http://drive.lasuite.svc.cluster.local:8000"
[[routes]]
host_prefix = "mail"
backend = "http://messages.lasuite.svc.cluster.local:8000"
[[routes]]
host_prefix = "chat"
backend = "http://conversations.lasuite.svc.cluster.local:8000"
websocket = true # Vercel AI SDK streaming
[[routes]]
host_prefix = "people"
backend = "http://people.lasuite.svc.cluster.local:8000"
[[routes]]
host_prefix = "src"
backend = "http://gitea.devtools.svc.cluster.local:3000"
websocket = true # Gitea Actions runner
[[routes]]
host_prefix = "auth"
backend = "http://hydra.ory.svc.cluster.local:4444"
[[routes]]
host_prefix = "s3"
backend = "http://seaweedfs-filer.storage.svc.cluster.local:8333"

View File

@@ -0,0 +1,52 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: pingora
namespace: ingress
spec:
replicas: 1
selector:
matchLabels:
app: pingora
template:
metadata:
labels:
app: pingora
annotations:
# Pingora terminates TLS at the mesh boundary; sidecar injection is disabled here
linkerd.io/inject: disabled
spec:
containers:
- name: pingora
image: ghcr.io/sunbeam-studio/pingora:latest
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
- name: turn-udp
containerPort: 3478
protocol: UDP
# TURN relay range 4915249252 exposed via hostPort in local overlay
volumeMounts:
- name: config
mountPath: /etc/pingora
readOnly: true
- name: tls
mountPath: /etc/tls
readOnly: true
resources:
limits:
memory: 64Mi
requests:
memory: 32Mi
cpu: 50m
volumes:
- name: config
configMap:
name: pingora-config
- name: tls
secret:
secretName: pingora-tls

View File

@@ -0,0 +1,24 @@
apiVersion: v1
kind: Service
metadata:
name: pingora
namespace: ingress
spec:
selector:
app: pingora
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
- name: https
port: 443
targetPort: 443
protocol: TCP
- name: turn-udp
port: 3478
targetPort: 3478
protocol: UDP
# TURN relay ports 4915249252 are forwarded via hostPort on the pod (see deployment).
# Kubernetes Services do not support port ranges; UDP relay is handled at the node level.