apiVersion: openclaw.rocks/v1alpha1 kind: OpenClawInstance metadata: name: openclaw spec: # Pin the gateway image to an immutable version tag. Running `latest` with # pullPolicy=IfNotPresent let a stale node-cached image (old build, state # schema v1) fight the PVC's DB migrated by a newer build (schema v15), # crash-looping the container. Bump this tag alongside upstream releases. image: repository: ghcr.io/openclaw/openclaw tag: "2026.9.3" # Workaround for paperclipinc/openclaw-operator#607: the operator mounts the # PVC root directly at /home/openclaw/.openclaw and only fsGroup is applied, # so the mount root stays owned by root. OpenClaw >= 2026.9 fchmods its config # dir when writing openclaw.json, which fails with EPERM for a non-owner. # This one-shot init container chowns the mount root to the pod UID. initContainers: - name: fix-data-owner image: docker.io/library/busybox:1.37 command: ["sh", "-c", "chown 1000:1000 /data && ls -ld /data"] securityContext: runAsUser: 0 runAsNonRoot: false allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: ["ALL"] add: ["CHOWN"] seccompProfile: type: RuntimeDefault volumeMounts: - name: data mountPath: /data # Provider API keys come from the SOPS-encrypted Secret below. # The gateway token is auto-generated by the operator (no mDNS pairing in k8s). envFrom: - secretRef: name: openclaw-api-keys storage: persistence: enabled: true size: 10Gi storageClass: longhorn networking: ingress: enabled: true className: traefik hosts: - host: openclaw.lan security: # Operator defaults forceHTTPS=true, which pins the Traefik router to # the websecure entrypoint only (404 on plain HTTP). Disabled since # this is a LAN-internal, token-auth-only endpoint without TLS. forceHTTPS: false annotations: external-dns.alpha.kubernetes.io/enabled: "true" # Python toolchain init container: lets skills/MCP servers use uv, and lets # the agent install python tools user-level (~/.local on the PVC) without root. runtimeDeps: python: true # Headless Chromium sidecar for browser automation (scraping, screenshots, # browser-based integrations). The operator injects CHROMIUM_URL into the # gateway and points the "default" and "chrome" browser profiles at its CDP # endpoint. Persistent profile keeps cookies/logins across pod restarts. chromium: enabled: true image: repository: chromedp/headless-shell tag: "stable" resources: requests: cpu: 250m memory: 512Mi limits: cpu: "1" memory: 2Gi persistence: enabled: true size: 2Gi storageClass: longhorn resources: requests: cpu: 250m memory: 512Mi limits: cpu: "2" memory: 4Gi