apiVersion: apps/v1 kind: Deployment metadata: name: hermes-agent namespace: customer1 spec: replicas: 1 selector: matchLabels: app: hermes-agent template: metadata: labels: app: hermes-agent spec: # 1. Pod-level security context to ensure volumes inherit the right group securityContext: fsGroup: 1000 # 2. Define our shared bridge volumes volumes: - name: hermes-home persistentVolumeClaim: claimName: hermes-agent-pvc - name: hermes-agent-src emptyDir: {} - name: hermes-workspace emptyDir: {} - name: hermes-webui-app emptyDir: {} initContainers: # 3. K8s workaround: Copy the agent source code into the shared emptyDir - name: copy-agent-source image: nousresearch/hermes-agent:latest command: - "sh" - "-c" - "cp -a /opt/hermes/. /shared-src/ && chown -R 1024:1000 /shared-src /shared-home" securityContext: runAsUser: 0 # Run as root briefly to copy and fix permissions runAsNonRoot: false volumeMounts: - name: hermes-agent-src mountPath: /shared-src - name: hermes-home mountPath: /shared-home - name: copy-webui-app image: busybox:latest command: - "sh" - "-c" # Copy the image's built-in /app to our shared volume, then give user 1024 ownership - "chown -R 1024:1000 /shared-app" securityContext: runAsUser: 0 runAsNonRoot: false volumeMounts: - name: hermes-webui-app mountPath: /shared-app containers: # ========================================== # CONTAINER 1: HERMES AGENT # ========================================== - name: hermes-agent image: nousresearch/hermes-agent:latest args: ["gateway", "run"] ports: - containerPort: 8642 env: - name: HOME value: "/home/hermes" - name: HERMES_HOME value: "/home/hermes/.hermes" - name: HERMES_UID value: "1024" - name: HERMES_GID value: "1000" - name: TELEGRAM_BOT_TOKEN valueFrom: secretKeyRef: name: hermes-secrets key: TELEGRAM_BOT_TOKEN - name: XAI_API_KEY valueFrom: secretKeyRef: name: xai-apikey key: XAI_API_KEY - name: TELEGRAM_ALLOWED_USERS value: "7528130947" # === Local vLLM (OpenAI-compatible) === - name: OPENAI_BASE_URL value: "http://openclaw-brain-service.customer1.svc.cluster.local:8000/v1" # ← adjust if your service name differs - name: HERMES_MODEL_PROVIDER value: xai - name: HERMES_MODEL value: grok-4.20-0309-reasoning - name: OPENAI_API_KEY value: "dummy" volumeMounts: - name: hermes-home mountPath: /home/hermes/.hermes - name: hermes-agent-src mountPath: /opt/hermes securityContext: runAsUser: 1024 runAsGroup: 1000 runAsNonRoot: true allowPrivilegeEscalation: true # ========================================== # CONTAINER 2: HERMES WEBUI # ========================================== - name: hermes-webui image: ghcr.io/nesquena/hermes-webui:latest ports: - containerPort: 8787 env: - name: HERMES_WEBUI_HOST value: "0.0.0.0" - name: HERMES_WEBUI_PORT value: "8787" - name: HERMES_WEBUI_STATE_DIR value: "/home/hermeswebui/.hermes/webui" - name: WANTED_UID value: "1024" - name: WANTED_GID value: "1000" volumeMounts: - name: hermes-home mountPath: /home/hermeswebui/.hermes # This is where the WebUI looks for the agent source code to run `uv pip install` - name: hermes-agent-src mountPath: /home/hermeswebui/.hermes/hermes-agent - name: hermes-workspace mountPath: /workspace - name: hermes-webui-app mountPath: /app resources: requests: memory: 500Mi cpu: "100m" limits: memory: 1Gi cpu: "500m" securityContext: runAsUser: 1024 runAsGroup: 1000 runAsNonRoot: true allowPrivilegeEscalation: false --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: hermes-agent-pvc namespace: customer1 spec: accessModes: - ReadWriteOnce resources: requests: storage: 25Gi