Files
alva/docs/DRIFT.md
T
Claude 03f1ef20f6 Allt i Kubernetes: containrar, manifest, orkestertjänst och CI
Målarkitekturen ur Master Prompt som kod:

- Webben containeriserad (flerstegs-Dockerfile → oprivilegierad nginx
  med SPA-fallback, hashade assets cachas hårt, säkerhetsheaders).
- AI-orkestern som egen tjänst (services/ai-orkester): samma routing
  och AI-regler som edge-funktionen men körbar som pod — egen
  HS256-JWT-verifiering (fail closed), /halsa, storleksgränser,
  read-only container som kör som node-användaren. Livetestad:
  hälsokontroll ok, 401 utan/med ogiltig token, 400-validering bakom
  giltig JWT.
- Kubernetes-manifest (infra/k8s, kustomize): namespace, Deployments
  med readiness/liveness och åtstramad securityContext, Services,
  HPA 2–10 pods på 70 % CPU, PodDisruptionBudgets, Ingress med TLS
  via cert-manager, secret-mall (riktiga värden skapas utanför git).
- Klienten väljer AI-väg vid bygget: VITE_AI_ORKESTER_URL → tjänsten
  i klustret, annars Supabase-edge-funktionen. Samma orkester i båda,
  låst av paritetstest.
- CI-arbetsflöde: tester + produktionsbygge + verifierande
  containerbyggen av båda bilderna på varje push/PR.
- docs/DRIFT.md: arkitekturdiagram, driftsättningssteg, skalning,
  och vad som återstår mot full självhostning.

Verifierat: 27 vitest-tester gröna, produktionsbygge ok, alla
K8s-manifest YAML-validerade, orkestertjänsten livetestad,
Playwright-röktest grönt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-03 01:27:54 +00:00

69 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Guidad Felsökning Drift i Kubernetes
Målarkitekturen ur [Master Prompt](MASTER-PROMPT.md) som kod: allt körbart i kluster, med secrets för plattformsnycklarna och CI som verifierar både kod och containerbyggen.
## Arkitektur
```mermaid
flowchart LR
T[Tekniker] -->|HTTPS| I[Ingress + TLS]
I -->|/| W[web\n210 pods, HPA]
I -->|/api/ai| A[ai-orkester\n210 pods, HPA]
A -->|Claude API| C[(Anthropic)]
W & A -.->|auth + data| S[(Supabase\nPostgres · Auth)]
K[Secret: felsokning-hemligheter] --> A
```
| Komponent | Vad | Var |
| --- | --- | --- |
| `web` | SPA:n bakom oprivilegierad nginx (`Dockerfile`, `docker/nginx.conf`) | Deployment + Service + HPA + PDB |
| `ai-orkester` | AI-orkestern som egen tjänst (`services/ai-orkester`) — samma routing som edge-funktionen, med egen JWT-verifiering och `/halsa` | Deployment + Service + HPA + PDB |
| Hemligheter | `ANTHROPIC_API_KEY` + `SUPABASE_JWT_SECRET` | Secret `felsokning-hemligheter` — aldrig i bilder eller manifest |
| Databas & auth | Postgres (händelselogg, RLS, `hamta_delat_arende`) och inloggning | Supabase — managerad, eller självhostad Supabase i klustret när det steget tas |
Klienten väljer AI-väg vid byggtillfället: med `VITE_AI_ORKESTER_URL` satt går anropen till orkestertjänsten i klustret; utan den används Supabase-edge-funktionen. Samma orkester (modeller, systemprompter, scheman) i båda.
## Driftsätta
```sh
# 1. Bygg och publicera bilderna (ersätt registry i infra/k8s/*.yaml)
docker build -t ghcr.io/ORG/guidad-felsokning-web \
--build-arg VITE_SUPABASE_URL=\
--build-arg VITE_SUPABASE_PUBLISHABLE_KEY=\
--build-arg VITE_SUPABASE_PROJECT_ID=\
--build-arg VITE_AI_ORKESTER_URL=https://app.exempel.se .
docker build -t ghcr.io/ORG/guidad-felsokning-ai-orkester services/ai-orkester
docker push ghcr.io/ORG/guidad-felsokning-web
docker push ghcr.io/ORG/guidad-felsokning-ai-orkester
# 2. Skapa secret:en (eller använd External Secrets/Sealed Secrets)
kubectl create namespace guidad-felsokning
kubectl -n guidad-felsokning create secret generic felsokning-hemligheter \
--from-literal=anthropic-api-key='sk-ant-…' \
--from-literal=supabase-jwt-secret='…'
# 3. Applicera manifesten
kubectl apply -k infra/k8s
# 4. Verifiera
kubectl -n guidad-felsokning get pods
curl https://app.exempel.se/halsa # → {"status":"ok"}
```
Byt domän och cert-issuer i `infra/k8s/ingress.yaml`.
## Skalning och robusthet
- **HPA** 210 pods per tjänst på 70 % CPU; **PDB** håller minst en pod uppe vid noddränering.
- Båda containrarna kör **non-root** utan capabilities; orkestern dessutom med read-only rotfilsystem.
- **Hälsokontroller**: nginx svarar på `/`, orkestern på `/halsa` (readiness + liveness + Docker HEALTHCHECK).
- Orkestern **failar closed**: utan nyckel/JWT-hemlighet svarar den 503, utan giltig JWT 401.
## CI
`.github/workflows/ci.yml` kör tester + produktionsbygge och verifierar båda Dockerfilerna på varje push/PR. Publicering till registry och `kubectl apply` läggs i ett separat, behörighetsstyrt deploy-flöde (t.ex. environments med godkännande eller GitOps via Argo CD/Flux).
## Kvar mot full självhostning
Synk, Live Share-funktionen och inloggningen går fortfarande mot Supabase (managerad Postgres + Auth). Nästa steg för "allt i kluster" är självhostad Supabase eller ett eget API-lager över Postgres i klustret — händelsemodellen är redan API-klar, så det bytet påverkar inte klienten.