# services/openclaw/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: openclaw namespace: openclaw labels: app: openclaw spec: replicas: 1 revisionHistoryLimit: 2 strategy: type: Recreate selector: matchLabels: app: openclaw template: metadata: labels: app: openclaw annotations: ai.bstein.dev/role: testing-triage ai.bstein.dev/placement: gateway lane (titan-20) spec: serviceAccountName: openclaw-triage automountServiceAccountToken: true securityContext: fsGroup: 1000 seccompProfile: type: RuntimeDefault affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - titan-20 initContainers: - name: init-config image: busybox:1.37 imagePullPolicy: IfNotPresent command: - sh - -c - | set -e cp /config/openclaw.json /home/node/.openclaw/openclaw.json mkdir -p /home/node/.openclaw/workspace cp /config/AGENTS.md /home/node/.openclaw/workspace/AGENTS.md securityContext: runAsUser: 1000 runAsGroup: 1000 volumeMounts: - name: home mountPath: /home/node/.openclaw - name: config mountPath: /config 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 -e cp "$(command -v kubectl)" /tools/kubectl chmod 0755 /tools/kubectl volumeMounts: - name: tools mountPath: /tools resources: requests: cpu: 25m memory: 32Mi limits: cpu: 100m memory: 64Mi containers: - name: gateway image: ghcr.io/openclaw/openclaw:slim@sha256:ca134367c291b982ec301038af4602f397c7f90cc6c6d263c12a78a5fe1bde57 imagePullPolicy: IfNotPresent command: - node - /app/dist/index.js - gateway - run ports: - name: gateway containerPort: 18789 protocol: TCP env: - name: HOME value: /home/node - name: OPENCLAW_CONFIG_DIR value: /home/node/.openclaw - name: NODE_ENV value: production - name: PATH value: /home/node/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - name: VICTORIA_METRICS_URL value: http://victoria-metrics-single-server.monitoring.svc.cluster.local:8428 - name: JENKINS_BASE_URL value: http://jenkins.jenkins.svc.cluster.local:8080 - name: GITEA_BASE_URL value: https://scm.bstein.dev - name: GRAFANA_BASE_URL value: https://metrics.bstein.dev - name: OPENCLAW_GATEWAY_TOKEN valueFrom: secretKeyRef: name: openclaw-secrets key: OPENCLAW_GATEWAY_TOKEN volumeMounts: - name: home mountPath: /home/node/.openclaw - name: tmp mountPath: /tmp - name: tools mountPath: /home/node/.local/bin readinessProbe: exec: command: - node - -e - "require('http').get('http://127.0.0.1:18789/readyz', r => process.exit(r.statusCode < 400 ? 0 : 1)).on('error', () => process.exit(1))" initialDelaySeconds: 20 periodSeconds: 10 timeoutSeconds: 5 livenessProbe: exec: command: - node - -e - "require('http').get('http://127.0.0.1:18789/healthz', r => process.exit(r.statusCode < 400 ? 0 : 1)).on('error', () => process.exit(1))" initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 10 securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL resources: requests: cpu: 250m memory: 512Mi limits: cpu: "1" memory: 2Gi volumes: - name: home emptyDir: {} - name: config configMap: name: openclaw-config - name: tmp emptyDir: {} - name: tools emptyDir: {}