diff --git a/services/hermes/agent-deployment.yaml b/services/hermes/agent-deployment.yaml index ac20fb222..4eb5f3053 100644 --- a/services/hermes/agent-deployment.yaml +++ b/services/hermes/agent-deployment.yaml @@ -227,9 +227,9 @@ spec: image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f imagePullPolicy: IfNotPresent command: [/opt/hermes/.venv/bin/hermes] - args: [gateway, run] + args: [gateway, run, --no-supervise] ports: - - {name: dashboard, containerPort: 9119, protocol: TCP} + - {name: api, containerPort: 8642, protocol: TCP} env: - {name: HERMES_HOME, value: /opt/data} - {name: HERMES_AUTH_FILE, value: /shared-auth/auth.json} @@ -239,10 +239,12 @@ spec: - {name: HERDR_CONFIG_PATH, value: /opt/data/home/.config/herdr/config.toml} - {name: HERDR_SOCKET_PATH, value: /opt/data/herdr/herdr.sock} - {name: PATH, value: /opt/data/tools/bin:/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, value: "0"} - {name: HERMES_DASHBOARD_PUBLIC_URL, value: https://agent.hermes.bstein.dev} + - {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://agent.hermes.bstein.dev} volumeMounts: - {name: home, mountPath: /opt/data} - {name: provider-auth, mountPath: /shared-auth} @@ -250,17 +252,17 @@ spec: - {name: auth-patch, mountPath: /opt/hermes/hermes_cli/auth.py, subPath: auth.py} - {name: coordinator, mountPath: /opt/data/home/.local/bin/herdr-dispatch, subPath: herdr_dispatch.py, readOnly: true} startupProbe: - httpGet: {path: /api/status, port: dashboard} + tcpSocket: {port: api} periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 60 readinessProbe: - httpGet: {path: /api/status, port: dashboard} + tcpSocket: {port: api} initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 livenessProbe: - httpGet: {path: /api/status, port: dashboard} + tcpSocket: {port: api} initialDelaySeconds: 90 periodSeconds: 30 timeoutSeconds: 10 @@ -273,6 +275,63 @@ spec: resources: requests: {cpu: 250m, memory: 512Mi} limits: {cpu: "2", memory: 4Gi} + - name: webui + image: registry.bstein.dev/bstein/hermes-webui@sha256:a771858bd668d25e19c74864baea5425101c8cd5215d1ba3a312f3312ce6c5e1 + imagePullPolicy: IfNotPresent + command: [/bin/sh, -ec] + args: + - | + api_key="$(sed -n 's/^API_SERVER_KEY=//p' /opt/data/.env | tail -n 1)" + test -n "${api_key}" + export API_SERVER_KEY="${api_key}" + export HERMES_WEBUI_GATEWAY_API_KEY="${api_key}" + exec /opt/hermes/.venv/bin/python /opt/hermes-webui/server.py + ports: + - {name: dashboard, containerPort: 8787, protocol: TCP} + env: + - {name: HERMES_HOME, value: /opt/data} + - {name: HERMES_AUTH_FILE, value: /shared-auth/auth.json} + - {name: HOME, value: /opt/data/home} + - {name: HERMES_WEBUI_AGENT_DIR, value: /opt/hermes} + - {name: HERMES_WEBUI_HOST, value: 0.0.0.0} + - {name: HERMES_WEBUI_PORT, value: "8787"} + - {name: HERMES_WEBUI_STATE_DIR, value: /opt/data/webui} + - {name: HERMES_WEBUI_DEFAULT_WORKSPACE, value: /opt/data/workspace} + - {name: HERMES_WEBUI_CHAT_BACKEND, value: gateway} + - {name: HERMES_WEBUI_GATEWAY_BASE_URL, value: http://127.0.0.1:8642} + - {name: HERMES_WEBUI_GATEWAY_USE_RUNS_API, value: "true"} + - {name: HERMES_WEBUI_SKIP_ONBOARDING, value: "1"} + - {name: HERMES_WEBUI_SECURE, value: "1"} + - {name: HERMES_WEBUI_ALLOWED_ORIGINS, value: https://agent.hermes.bstein.dev} + - {name: HERMES_WEBUI_TRUST_FORWARDED_HOST, value: "1"} + - {name: HERMES_WEBUI_TRUST_FORWARDED_PROTO, value: "1"} + volumeMounts: + - {name: home, mountPath: /opt/data} + - {name: provider-auth, mountPath: /shared-auth, readOnly: true} + - {name: tmp, mountPath: /tmp} + readinessProbe: + httpGet: {path: /health, port: dashboard} + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + livenessProbe: + httpGet: {path: /health, port: dashboard} + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: [ALL] + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 10000 + runAsGroup: 10000 + seccompProfile: + type: RuntimeDefault + resources: + requests: {cpu: 50m, memory: 128Mi} + limits: {cpu: 750m, memory: 1Gi} - name: herdr-server image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f imagePullPolicy: IfNotPresent @@ -351,3 +410,6 @@ spec: defaultMode: 0555 - name: auth-patch emptyDir: {} + - name: tmp + emptyDir: + sizeLimit: 256Mi diff --git a/services/hermes/deployment.yaml b/services/hermes/deployment.yaml index 9149bfd4d..f34f7f6d9 100644 --- a/services/hermes/deployment.yaml +++ b/services/hermes/deployment.yaml @@ -242,13 +242,11 @@ spec: args: - gateway - run + - --no-supervise ports: - name: api containerPort: 8642 protocol: TCP - - name: dashboard - containerPort: 9119 - protocol: TCP env: - name: HERMES_HOME value: /opt/data @@ -259,11 +257,7 @@ spec: - 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" + value: "0" - name: HERMES_DASHBOARD_PUBLIC_URL value: https://triage.hermes.bstein.dev - name: API_SERVER_ENABLED @@ -325,23 +319,20 @@ spec: mountPath: /opt/data/workspace/skills/tune-atlas-alerts readOnly: true startupProbe: - httpGet: - path: /api/status - port: dashboard + tcpSocket: + port: api periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 60 readinessProbe: - httpGet: - path: /api/status - port: dashboard + tcpSocket: + port: api initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 livenessProbe: - httpGet: - path: /api/status - port: dashboard + tcpSocket: + port: api initialDelaySeconds: 90 periodSeconds: 30 timeoutSeconds: 10 @@ -352,6 +343,63 @@ spec: limits: cpu: "2" memory: 4Gi + - name: webui + image: registry.bstein.dev/bstein/hermes-webui@sha256:a771858bd668d25e19c74864baea5425101c8cd5215d1ba3a312f3312ce6c5e1 + imagePullPolicy: IfNotPresent + command: [/bin/sh, -ec] + args: + - | + api_key="$(sed -n 's/^API_SERVER_KEY=//p' /opt/data/.env | tail -n 1)" + test -n "${api_key}" + export API_SERVER_KEY="${api_key}" + export HERMES_WEBUI_GATEWAY_API_KEY="${api_key}" + exec /opt/hermes/.venv/bin/python /opt/hermes-webui/server.py + ports: + - {name: dashboard, containerPort: 8787, protocol: TCP} + env: + - {name: HERMES_HOME, value: /opt/data} + - {name: HERMES_AUTH_FILE, value: /shared-auth/auth.json} + - {name: HOME, value: /opt/data/home} + - {name: HERMES_WEBUI_AGENT_DIR, value: /opt/hermes} + - {name: HERMES_WEBUI_HOST, value: 0.0.0.0} + - {name: HERMES_WEBUI_PORT, value: "8787"} + - {name: HERMES_WEBUI_STATE_DIR, value: /opt/data/webui} + - {name: HERMES_WEBUI_DEFAULT_WORKSPACE, value: /opt/data/workspace} + - {name: HERMES_WEBUI_CHAT_BACKEND, value: gateway} + - {name: HERMES_WEBUI_GATEWAY_BASE_URL, value: http://127.0.0.1:8642} + - {name: HERMES_WEBUI_GATEWAY_USE_RUNS_API, value: "true"} + - {name: HERMES_WEBUI_SKIP_ONBOARDING, value: "1"} + - {name: HERMES_WEBUI_SECURE, value: "1"} + - {name: HERMES_WEBUI_ALLOWED_ORIGINS, value: https://triage.hermes.bstein.dev} + - {name: HERMES_WEBUI_TRUST_FORWARDED_HOST, value: "1"} + - {name: HERMES_WEBUI_TRUST_FORWARDED_PROTO, value: "1"} + volumeMounts: + - {name: home, mountPath: /opt/data} + - {name: provider-auth, mountPath: /shared-auth, readOnly: true} + - {name: tmp, mountPath: /tmp} + readinessProbe: + httpGet: {path: /health, port: dashboard} + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + livenessProbe: + httpGet: {path: /health, port: dashboard} + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: [ALL] + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 10000 + runAsGroup: 10000 + seccompProfile: + type: RuntimeDefault + resources: + requests: {cpu: 50m, memory: 128Mi} + limits: {cpu: 750m, memory: 1Gi} volumes: - name: home persistentVolumeClaim: @@ -373,6 +421,9 @@ spec: defaultMode: 0555 - name: auth-patch emptyDir: {} + - name: tmp + emptyDir: + sizeLimit: 256Mi - name: triage-skill configMap: name: hermes-triage-skill