Research-Stack/4-Infrastructure/k3s-flake/manifests/ingress/ingress.yaml
Brandon Schneider a031a73dfe fix(infra): standardize k3s cluster — Traefik, ingress, architecture docs, Ray GPU workers
Architecture alignment:
- Rewrite k3s-server.nix from aspirational role=server to actual role=agent
  (cupfox is the real control-plane at 100.110.163.82:6443)
- Update flake.nix: correct serverAddr for all nodes, annotate dead nodes,
  fix hostname from nixos-laptop to nixos
- Update join-agent.sh default SERVER to cupfox
- Document actual vs intended architecture in comments

Ingress:
- Add rs-apps-books Ingress for audiobookshelf (/apps/books → media ns)
- Add strip-apps-books middleware for prefix stripping
- Create ray-ingress.yaml for Ray dashboard at /server/ray

Ray:
- Fix raycluster.yaml: enable dashboard, mount /dev/dri on gpu-workers
- Point gpu-workers to qfox-1 (was neon-64gb)
- Remove nvidia.com/gpu resource dependency (use /dev/dri via Mesa)

Security:
- Move OPENID_CLIENT_SECRET from plaintext to K8s Secret ref
- Update manifest to use valueFrom.secretKeyRef

Cleanup:
- Remove 53 committed test PNG screenshots from git tracking
- Remove auth-state.json from git tracking
- Add *.png, *.json to tests/.gitignore

Build: no build needed
2026-05-31 23:13:04 -05:00

313 lines
13 KiB
YAML

# Traefik Ingress — canonical path-based routing for researchstack.info
#
# This is the single source of truth for URL → service mapping inside k3s.
# The public edge Caddy terminates TLS and forwards to Traefik's entrypoint.
# Traefik handles path routing, prefix stripping, and forward-auth.
#
# Middleware annotation format: <namespace>-<middleware-name>@kubernetescrd
#
# Split into per-route Ingresses so each gets its own middleware chain:
# - /apps/*, /server/* → forward_auth (Authentik) + strip-prefix
# - /api/* → strip-prefix only (token-auth, no SSO)
# - / → forward_auth (Authentik), no strip
# - auth.* → no middleware (Authentik itself)
# ═══════════════════════════════════════════════════════════════════════════
# /apps/chat/* → Hermes (SSO-gated)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-apps-chat
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: services-authentik-forward-auth@kubernetescrd,services-strip-apps-chat@kubernetescrd
spec:
rules:
- host: researchstack.info
http:
paths:
- path: /apps/chat
pathType: Prefix
backend:
service:
name: hermes
port:
number: 80
# ═══════════════════════════════════════════════════════════════════════════
# /apps/budget/* → Actual Budget (SSO-gated)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-apps-budget
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: services-authentik-forward-auth@kubernetescrd,services-strip-apps-budget@kubernetescrd
spec:
rules:
- host: researchstack.info
http:
paths:
- path: /apps/budget
pathType: Prefix
backend:
service:
name: actual-budget
port:
number: 5006
# ═══════════════════════════════════════════════════════════════════════════
# /apps/books/* → Audiobookshelf (SSO-gated)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-apps-books
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: services-authentik-forward-auth@kubernetescrd,services-strip-apps-books@kubernetescrd
spec:
rules:
- host: researchstack.info
http:
paths:
- path: /apps/books
pathType: Prefix
backend:
service:
name: audiobookshelf
port:
number: 80
---
# ═══════════════════════════════════════════════════════════════════════════
# /server/status/* → Uptime Kuma (SSO-gated)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-server-status
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: services-authentik-forward-auth@kubernetescrd,services-strip-server-status@kubernetescrd
spec:
rules:
- host: researchstack.info
http:
paths:
- path: /server/status
pathType: Prefix
backend:
service:
name: uptime-kuma
port:
number: 3001
# ═══════════════════════════════════════════════════════════════════════════
# /server/dash/* → Homarr (SSO-gated)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-server-dash
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: services-authentik-forward-auth@kubernetescrd,services-strip-server-dash@kubernetescrd
spec:
rules:
- host: researchstack.info
http:
paths:
- path: /server/dash
pathType: Prefix
backend:
service:
name: homarr
port:
number: 7575
# ═══════════════════════════════════════════════════════════════════════════
# /server/vault/* → Vaultwarden (SSO-gated)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-server-vault
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: services-authentik-forward-auth@kubernetescrd,services-strip-server-vault@kubernetescrd
spec:
rules:
- host: researchstack.info
http:
paths:
- path: /server/vault
pathType: Prefix
backend:
service:
name: vaultwarden
port:
number: 80
# ═══════════════════════════════════════════════════════════════════════════
# /api/cred/* → Credential Server (token-auth, no SSO)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-api-cred
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: services-strip-api-cred@kubernetescrd
spec:
rules:
- host: researchstack.info
http:
paths:
- path: /api/cred
pathType: Prefix
backend:
service:
name: credential-server
port:
number: 8444
# ═══════════════════════════════════════════════════════════════════════════
# /api/registry/* → Registry API (token-auth, no SSO)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-api-registry
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: services-strip-api-registry@kubernetescrd
spec:
rules:
- host: researchstack.info
http:
paths:
- path: /api/registry
pathType: Prefix
backend:
service:
name: registry-api
port:
number: 8080
# ═══════════════════════════════════════════════════════════════════════════
# /api/jobs/* → Job Router (token-auth, no SSO)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-api-jobs
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: services-strip-api-jobs@kubernetescrd
spec:
rules:
- host: researchstack.info
http:
paths:
- path: /api/jobs
pathType: Prefix
backend:
service:
name: jobs-api
port:
number: 8080
# ═══════════════════════════════════════════════════════════════════════════
# /api/blobs/* → Blob Plane (token-auth, no SSO)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-api-blobs
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: services-strip-api-blobs@kubernetescrd
spec:
rules:
- host: researchstack.info
http:
paths:
- path: /api/blobs
pathType: Prefix
backend:
service:
name: blobs-api
port:
number: 8080
# ═══════════════════════════════════════════════════════════════════════════
# / → Homer landing page (SSO-gated, no strip)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-landing
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: services-authentik-forward-auth@kubernetescrd
traefik.ingress.kubernetes.io/router.priority: "1"
spec:
rules:
- host: researchstack.info
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: homer
port:
number: 8080
# ═══════════════════════════════════════════════════════════════════════════
# auth.researchstack.info → Authentik (stable OIDC issuer, no middleware)
# ═══════════════════════════════════════════════════════════════════════════
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rs-auth
namespace: services
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: auth.researchstack.info
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: authentik-server
port:
number: 80