Files
vhaudiquet f2d7fe7bcc openclaw: pin image to 2026.9.3 and chown PVC mount root (operator#607)
- Pin gateway image to immutable tag 2026.9.3: the stale node-cached
  'latest' (old build, state schema v1) crash-looped against the PVC's
  DB already migrated to schema v15/16.
- Add fix-data-owner init container: the operator mounts the PVC root
  at /home/openclaw/.openclaw with fsGroup only, leaving the mount root
  owned by root; OpenClaw >= 2026.9 fchmods its config dir on write and
  fails with EPERM (paperclipinc/openclaw-operator#607).
- Ran one-time 'openclaw doctor --fix --non-interactive' against the
  PVC to complete the 2.0 workspace-state migration.
2026-09-10 00:59:25 +02:00

89 lines
3.0 KiB
YAML

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