260 lines
8.7 KiB
YAML
260 lines
8.7 KiB
YAML
# services/hermes-chat/deployment.yaml
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: hermes-chat
|
|
namespace: hermes-chat
|
|
labels:
|
|
app: hermes-chat
|
|
spec:
|
|
replicas: 1
|
|
revisionHistoryLimit: 2
|
|
progressDeadlineSeconds: 1800
|
|
strategy:
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app: hermes-chat
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: hermes-chat
|
|
annotations:
|
|
ai.bstein.dev/model: openai-codex/gpt-5.6-terra with local gpt-oss:20b fallback
|
|
ai.bstein.dev/role: personal-chat-research
|
|
ai.bstein.dev/isolation: observer-only Kubernetes RBAC, private-service egress denied
|
|
ai.bstein.dev/session-reset: "20260802-consumer-pty-recovery"
|
|
ai.bstein.dev/frontend-fix: scope PTY attachment by selected conversation
|
|
ai.bstein.dev/user-boundary: one OIDC subject with an isolated PVC subdirectory
|
|
spec:
|
|
serviceAccountName: hermes-chat
|
|
automountServiceAccountToken: true
|
|
securityContext:
|
|
fsGroup: 10000
|
|
fsGroupChangePolicy: OnRootMismatch
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
affinity:
|
|
nodeAffinity:
|
|
requiredDuringSchedulingIgnoredDuringExecution:
|
|
nodeSelectorTerms:
|
|
- matchExpressions:
|
|
- key: kubernetes.io/arch
|
|
operator: In
|
|
values:
|
|
- arm64
|
|
- key: node-role.kubernetes.io/worker
|
|
operator: In
|
|
values:
|
|
- "true"
|
|
- key: kubernetes.io/hostname
|
|
operator: NotIn
|
|
values:
|
|
- titan-13
|
|
- titan-15
|
|
- titan-17
|
|
- titan-18
|
|
- titan-19
|
|
preferredDuringSchedulingIgnoredDuringExecution:
|
|
- weight: 100
|
|
preference:
|
|
matchExpressions:
|
|
- key: atlas.bstein.dev/spillover
|
|
operator: DoesNotExist
|
|
- weight: 90
|
|
preference:
|
|
matchExpressions:
|
|
- key: hardware
|
|
operator: In
|
|
values:
|
|
- rpi5
|
|
- weight: 50
|
|
preference:
|
|
matchExpressions:
|
|
- key: hardware
|
|
operator: In
|
|
values:
|
|
- rpi4
|
|
initContainers:
|
|
- name: migrate-user-sessions
|
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f
|
|
imagePullPolicy: IfNotPresent
|
|
command:
|
|
- /opt/hermes/bin/hermes-session-migrate
|
|
env:
|
|
- name: HERMES_HOME
|
|
value: /storage/users/4794ab8284a14d421eaeea3e
|
|
- name: HERMES_MIGRATE_SOURCE_HOME
|
|
value: /storage
|
|
- name: HERMES_MIGRATE_USER_ID
|
|
value: 26b56113-0ec5-40b0-be7d-c2cd862f9bbc
|
|
- name: HERMES_MIGRATE_SESSION_IDS
|
|
value: 20260802_182723_9f53f1,20260802_173527_9dc51b
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
runAsUser: 10000
|
|
runAsGroup: 10000
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
volumeMounts:
|
|
- name: home
|
|
mountPath: /storage
|
|
resources:
|
|
requests:
|
|
cpu: 25m
|
|
memory: 64Mi
|
|
limits:
|
|
cpu: 250m
|
|
memory: 256Mi
|
|
- name: init-config
|
|
image: busybox:1.37
|
|
imagePullPolicy: IfNotPresent
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
set -eu
|
|
user_home=/storage/users/4794ab8284a14d421eaeea3e
|
|
mkdir -p "${user_home}/workspace/skills" "${user_home}/home/.local/bin" "${user_home}/logs"
|
|
cp /config/config.yaml "${user_home}/config.yaml"
|
|
cp /config/SOUL.md "${user_home}/SOUL.md"
|
|
cp /config/AGENTS.md "${user_home}/workspace/AGENTS.md"
|
|
touch "${user_home}/.env"
|
|
if ! grep -q '^API_SERVER_KEY=' "${user_home}/.env"; then
|
|
api_key="$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | od -An -tx1 | tr -d ' \n')"
|
|
printf '\nAPI_SERVER_KEY=%s\n' "${api_key}" >> "${user_home}/.env"
|
|
fi
|
|
chmod 0600 "${user_home}/.env"
|
|
chown -R 10000:10000 "${user_home}"
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
runAsUser: 0
|
|
runAsGroup: 0
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
volumeMounts:
|
|
- name: home
|
|
mountPath: /storage
|
|
- name: config
|
|
mountPath: /config
|
|
readOnly: true
|
|
resources:
|
|
requests:
|
|
cpu: 25m
|
|
memory: 32Mi
|
|
limits:
|
|
cpu: 100m
|
|
memory: 64Mi
|
|
- name: install-kubectl
|
|
image: bitnami/kubectl@sha256:554ab88b1858e8424c55de37ad417b16f2a0e65d1607aa0f3fe3ce9b9f10b131
|
|
imagePullPolicy: IfNotPresent
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- |
|
|
set -eu
|
|
cp "$(command -v kubectl)" /tools/kubectl
|
|
chmod 0755 /tools/kubectl
|
|
chown 10000:10000 /tools/kubectl
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
runAsUser: 0
|
|
runAsGroup: 0
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
volumeMounts:
|
|
- name: tools
|
|
mountPath: /tools
|
|
resources:
|
|
requests:
|
|
cpu: 25m
|
|
memory: 32Mi
|
|
limits:
|
|
cpu: 100m
|
|
memory: 64Mi
|
|
containers:
|
|
- name: hermes-chat
|
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f
|
|
imagePullPolicy: IfNotPresent
|
|
args:
|
|
- gateway
|
|
- run
|
|
ports:
|
|
- name: dashboard
|
|
containerPort: 9119
|
|
protocol: TCP
|
|
env:
|
|
- name: HERMES_HOME
|
|
value: /opt/data
|
|
- name: HOME
|
|
value: /opt/data/home
|
|
- name: PATH
|
|
value: /opt/data/home/.local/bin:/opt/hermes/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
- name: HERMES_DASHBOARD
|
|
value: "1"
|
|
- name: HERMES_DASHBOARD_HOST
|
|
value: 0.0.0.0
|
|
- name: HERMES_DASHBOARD_PORT
|
|
value: "9119"
|
|
- name: HERMES_DASHBOARD_PUBLIC_URL
|
|
value: https://chat.bstein.dev
|
|
- name: HERMES_DASHBOARD_OIDC_ISSUER
|
|
value: https://sso.bstein.dev/realms/atlas
|
|
- name: HERMES_DASHBOARD_OIDC_CLIENT_ID
|
|
value: hermes-chat-dashboard
|
|
- name: HERMES_DASHBOARD_OIDC_SCOPES
|
|
value: openid profile email groups
|
|
- name: HERMES_DASHBOARD_OIDC_ALLOWED_USER_IDS
|
|
value: 26b56113-0ec5-40b0-be7d-c2cd862f9bbc
|
|
- name: API_SERVER_ENABLED
|
|
value: "true"
|
|
- name: API_SERVER_HOST
|
|
value: 0.0.0.0
|
|
- name: API_SERVER_PORT
|
|
value: "8642"
|
|
- name: API_SERVER_CORS_ORIGINS
|
|
value: https://chat.bstein.dev
|
|
volumeMounts:
|
|
- name: home
|
|
mountPath: /opt/data
|
|
subPath: users/4794ab8284a14d421eaeea3e
|
|
- name: tools
|
|
mountPath: /usr/local/bin/kubectl
|
|
subPath: kubectl
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /api/status
|
|
port: dashboard
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /api/status
|
|
port: dashboard
|
|
initialDelaySeconds: 90
|
|
periodSeconds: 30
|
|
timeoutSeconds: 10
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 768Mi
|
|
ephemeral-storage: 256Mi
|
|
limits:
|
|
cpu: "1"
|
|
memory: 2Gi
|
|
ephemeral-storage: 1Gi
|
|
volumes:
|
|
- name: home
|
|
persistentVolumeClaim:
|
|
claimName: hermes-chat-home
|
|
- name: config
|
|
configMap:
|
|
name: hermes-chat-config
|
|
- name: tools
|
|
emptyDir: {}
|