Repoints fc-chat, fc-ttsreader, knowledge, fc-llm-bridge (off the slow edge1 Pi5 10.0.57.17) and intranet (off the reimaged BLUEJAY-AI test laptop 10.0.56.132) to the GX10 (DGX Spark / GB10) Ollama over the PROD MetalLB VIP 10.0.57.201. GX10 serves gemma3:12b/gemma3:4b/qwen2.5:1.5b/nomic-embed-text/ llama3.2:1b on local NVMe, warm-pinned (keep_alive=-1). fc-chat default model qwen2.5-coder:7b -> gemma3:12b (the coder model won't pull reliably on the GX10; gemma3:12b is the warm fleet default + a better general-chat model). Other consumers keep their exact models. Inline comments referencing edge1/BLUEJAY-AI are now historical; the values are the GX10 VIP. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
221 lines
7.3 KiB
YAML
221 lines
7.3 KiB
YAML
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: intranet
|
|
---
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: intranet-vector-store
|
|
namespace: intranet
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
storageClassName: longhorn
|
|
resources:
|
|
requests:
|
|
storage: 1Gi
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: intranet-config
|
|
namespace: intranet
|
|
data:
|
|
KnowledgeApiKey: ""
|
|
TrustedHeaderSharedSecret: ""
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: intranet-web
|
|
namespace: intranet
|
|
labels:
|
|
app: intranet-web
|
|
spec:
|
|
replicas: 1
|
|
strategy:
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app: intranet-web
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: intranet-web
|
|
spec:
|
|
# notes-corpus-clone: shallow-clones the Notes docs corpus into an emptyDir so
|
|
# the IntranetSearch indexer has /srv/flowercore-notes/docs to index. Uses the
|
|
# trailing-dot FQDN (gitea-clusterip.gitea.svc.cluster.local.) to bypass the
|
|
# CoreDNS *.iamworkin.lan template that otherwise resolves the in-cluster service
|
|
# name to the Traefik VIP for musl / ndots:5 pods (search-domain appending).
|
|
# Cred: gitea-corpus-cred (in-ns secret with the canonical 1P bluejay read cred;
|
|
# mirrors the imperative gitea-flowercore-notes argocd repo-cred pattern).
|
|
initContainers:
|
|
- name: notes-corpus-clone
|
|
image: alpine/git:2.45.2
|
|
imagePullPolicy: IfNotPresent
|
|
envFrom:
|
|
- secretRef:
|
|
name: gitea-corpus-cred
|
|
env:
|
|
- name: GIT_LFS_SKIP_SMUDGE
|
|
value: "1"
|
|
command: ["/bin/sh", "-c"]
|
|
args:
|
|
- 'git clone --depth 1 http://$username:$password@gitea-clusterip.gitea.svc.cluster.local.:3000/bluejay/FlowerCore.Notes.git /srv/flowercore-notes && echo "notes corpus cloned; docs entries:" && ls /srv/flowercore-notes/docs | wc -l'
|
|
volumeMounts:
|
|
- name: notes-corpus
|
|
mountPath: /srv/flowercore-notes
|
|
containers:
|
|
- name: intranet-web
|
|
image: localhost/fc-intranet-web:v20260614-wave5-knowledgefleet-1458b4d
|
|
imagePullPolicy: Never
|
|
ports:
|
|
- containerPort: 5300
|
|
name: http
|
|
env:
|
|
- name: ASPNETCORE_ENVIRONMENT
|
|
value: Production
|
|
- name: ASPNETCORE_URLS
|
|
value: "http://+:5300"
|
|
# Embed backend = edge1 Ollama BY IPv4 (10.0.57.17:11434; has
|
|
# nomic-embed-text). The hostname edge1.iamworkin.lan is UNUSABLE from
|
|
# cluster pods: it resolves to an unroutable IPv6 (fdbc:56:*) and the
|
|
# CoreDNS *.iamworkin.lan template maps the name to the Traefik VIP, so
|
|
# embeds failed with "No route to host". Use a bare pod-routable IPv4.
|
|
# Backend is BLUEJAY-AI's GPU node (Ollama / Vulkan Iris Xe, INFRA VLAN
|
|
# 10.0.56.132) which embeds nomic-embed-text in ~160ms vs the edge1 Pi 5's
|
|
# ~3.2s for the same ~512-token chunk (~20x faster bulk embed), proven
|
|
# pod-routable from the intranet namespace 2026-06-13. The prior edge1 Pi 5
|
|
# backend (10.0.57.17:11434) remains a working fallback if BLUEJAY-AI is
|
|
# down. Bulk embed runs in the background; /health does not depend on it.
|
|
# Memory: feedback_pi5_nomic_embed_slow.
|
|
- name: IntranetSearch__OllamaBaseUrl
|
|
value: "http://10.0.57.201:11434"
|
|
# Notes docs corpus IS now mounted at /srv/flowercore-notes (see the
|
|
# notes-corpus-clone initContainer + notes-corpus-sync sidecar), so the
|
|
# IntranetSearch indexer is ENABLED. First-boot bulk embed of the corpus
|
|
# runs in the background via the edge1 Ollama backend above (~6s/chunk on
|
|
# the Pi 5); /health readiness does not depend on it, so the pod stays Ready.
|
|
- name: IntranetSearch__Enabled
|
|
value: "true"
|
|
# Page-reading override SQLite persistence on the writable PVC at
|
|
# /data. This backs pronunciation, notes, corrections, and
|
|
# page-profile metadata across pod restarts.
|
|
- name: PageReadingOverrides__DatabasePath
|
|
value: "/data/page-reading-overrides.db"
|
|
- name: KnowledgeFleetSearch__BaseUrl
|
|
value: "https://knowledge.iamworkin.lan"
|
|
- name: KnowledgeFleetSearch__ApiKey
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: intranet-config
|
|
key: KnowledgeApiKey
|
|
optional: true
|
|
- name: TrustedHeaderAuthentication__SharedSecret
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: intranet-config
|
|
key: TrustedHeaderSharedSecret
|
|
optional: true
|
|
resources:
|
|
requests:
|
|
memory: "256Mi"
|
|
cpu: "100m"
|
|
limits:
|
|
memory: "1Gi"
|
|
cpu: "1000m"
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 5300
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 5300
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
volumeMounts:
|
|
- name: vector-store
|
|
mountPath: /data
|
|
- name: notes-corpus
|
|
mountPath: /srv/flowercore-notes
|
|
readOnly: true
|
|
# notes-corpus-sync: keeps the mounted corpus fresh between pod restarts by
|
|
# pulling the Notes repo every 30 min (best-effort; the initContainer guarantees
|
|
# a fresh clone at pod start). Reuses the clone's origin (trailing-dot host + creds).
|
|
- name: notes-corpus-sync
|
|
image: alpine/git:2.45.2
|
|
imagePullPolicy: IfNotPresent
|
|
envFrom:
|
|
- secretRef:
|
|
name: gitea-corpus-cred
|
|
env:
|
|
- name: GIT_LFS_SKIP_SMUDGE
|
|
value: "1"
|
|
command: ["/bin/sh", "-c"]
|
|
args:
|
|
- 'while true; do sleep 1800; git -C /srv/flowercore-notes pull --depth 1 2>&1 | sed "s/^/[notes-corpus-sync] /" || true; done'
|
|
resources:
|
|
requests:
|
|
memory: "32Mi"
|
|
cpu: "10m"
|
|
limits:
|
|
memory: "128Mi"
|
|
cpu: "200m"
|
|
volumeMounts:
|
|
- name: notes-corpus
|
|
mountPath: /srv/flowercore-notes
|
|
volumes:
|
|
- name: vector-store
|
|
persistentVolumeClaim:
|
|
claimName: intranet-vector-store
|
|
- name: notes-corpus
|
|
emptyDir: {}
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: intranet-web
|
|
namespace: intranet
|
|
spec:
|
|
selector:
|
|
app: intranet-web
|
|
ports:
|
|
- port: 5300
|
|
targetPort: 5300
|
|
name: http
|
|
---
|
|
apiVersion: cert-manager.io/v1
|
|
kind: Certificate
|
|
metadata:
|
|
name: intranet-tls
|
|
namespace: intranet
|
|
spec:
|
|
secretName: intranet-tls
|
|
issuerRef:
|
|
name: step-ca-acme
|
|
kind: ClusterIssuer
|
|
dnsNames:
|
|
- intranet.iamworkin.lan
|
|
---
|
|
apiVersion: traefik.io/v1alpha1
|
|
kind: IngressRoute
|
|
metadata:
|
|
name: intranet
|
|
namespace: intranet
|
|
spec:
|
|
entryPoints:
|
|
- websecure
|
|
routes:
|
|
- match: Host(`intranet.iamworkin.lan`)
|
|
kind: Rule
|
|
services:
|
|
- name: intranet-web
|
|
port: 5300
|
|
tls:
|
|
secretName: intranet-tls
|