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: securityContext: fsGroup: 1000 runAsGroup: 1000 runAsUser: 1000 containers: - name: hermes-agent securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL seccompProfile: type: RuntimeDefault image: nousresearch/hermes-agent:latest command: ["/bin/bash", "-c"] args: - | set -euo pipefail echo "Hermes Agent starting (Telegram polling + full config persistence)..." HERMES_BIN="/opt/hermes/.venv/bin/hermes" if [ ! -x "$HERMES_BIN" ]; then echo "❌ hermes binary NOT FOUND at $HERMES_BIN" echo "Searching filesystem..." find / -name hermes -type f 2>/dev/null | head -10 || true exit 1 fi echo "✅ Found hermes at: $HERMES_BIN" # Copy config cp -f /etc/hermes/config.yaml /opt/data/config.yaml || true # Create symlink in a writable location (PVC) so it works when you exec in mkdir -p /opt/data/bin ln -sf "$HERMES_BIN" /opt/data/bin/hermes || true export PATH="/opt/data/bin:$PATH" echo "🚀 Starting hermes gateway..." exec "$HERMES_BIN" gateway run env: # === Hermes Home - REQUIRED for config persistence === - name: HERMES_HOME value: "/opt/data" - name: HOME value: "/opt/data" - name: XDG_CACHE_HOME value: "/opt/data/.cache" - name: XDG_CONFIG_HOME value: "/opt/data/.config" # === Telegram Configuration (polling only - no public exposure) === - 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.1-fast - name: OPENAI_API_KEY value: "dummy" # vLLM ignores this # === API Server (for external OpenAI-compatible clients) === - name: API_SERVER_ENABLED value: "true" - name: API_SERVER_HOST value: "0.0.0.0" - name: API_SERVER_PORT value: "8642" - name: API_SERVER_KEY value: "" # empty = no auth (tailnet-only, private) - name: API_SERVER_MODEL_NAME value: "hermes-agent" # === Optional === # - name: LOG_LEVEL # value: "INFO" volumeMounts: - name: hermes-data mountPath: /opt/data - name: hermes-configmap mountPath: /etc/hermes/config.yaml subPath: config.yaml readOnly: true resources: requests: memory: 2Gi cpu: "1" limits: memory: 4Gi cpu: "2" - name: hermes-webui image: ghcr.io/nesquena/hermes-webui:latest ports: - containerPort: 8787 env: - name: HERMES_HOME value: "/home/hermeswebui/.hermes" - 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: "1000" - name: WANTED_GID value: "1000" volumeMounts: - name: hermes-data mountPath: /home/hermeswebui/.hermes resources: requests: memory: 256Mi cpu: "100m" limits: memory: 512Mi cpu: "500m" securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL runAsUser: 1000 runAsGroup: 1000 seccompProfile: type: RuntimeDefault volumes: - name: hermes-configmap configMap: name: hermes-config - name: hermes-data persistentVolumeClaim: claimName: hermes-agent-pvc --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: hermes-agent-pvc namespace: customer1 spec: accessModes: - ReadWriteOnce resources: requests: storage: 25Gi