rdev/deployments/k8s/base/rdev-worker.yaml
jordan 3b35900a2d feat: enterprise worker pool with HTTP sidecar pattern
Implements horizontally-scalable worker pool architecture:
- claudebox-sidecar: HTTP server for Claude Code, git, and SDLC ops
- rdev-worker: standalone worker binary polling rdev-api for tasks
- HTTP client adapter for sidecar communication
- HPA with custom Prometheus metrics for autoscaling
- ServiceMonitor for metrics scraping

Code review fixes applied:
- URL-encode query parameters in GitStatus (Critical #1)
- Remove unused shellQuote function (Critical #2)
- Use stdlib strings.Split/TrimSpace (Critical #3)
- Add version injection via ldflags (Warning #4)
- Add debug logging for swallowed git/sdlc errors (Warning #5, #6)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 16:21:11 -07:00

170 lines
4.5 KiB
YAML

# Standalone worker deployment with claudebox sidecar.
# Workers poll rdev-api for tasks and execute them via HTTP calls to the local sidecar.
apiVersion: apps/v1
kind: Deployment
metadata:
name: rdev-worker
namespace: rdev
labels:
app.kubernetes.io/name: rdev-worker
app.kubernetes.io/part-of: rdev
spec:
replicas: 2
selector:
matchLabels:
app: rdev-worker
template:
metadata:
labels:
app: rdev-worker
app.kubernetes.io/name: rdev-worker
app.kubernetes.io/part-of: rdev
rdev.orchard9.ai/role: worker
spec:
containers:
# Main worker container - polls for tasks and orchestrates execution
- name: worker
image: ghcr.io/orchard9/rdev-worker:latest
imagePullPolicy: Always
env:
- name: RDEV_API_URL
value: "http://rdev-api.rdev.svc.cluster.local:8080"
- name: CLAUDEBOX_URL
value: "http://localhost:8080"
- name: RDEV_API_KEY
valueFrom:
secretKeyRef:
name: rdev-worker-credentials
key: api-key
- name: WORKER_ID
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: WORKER_POLL_INTERVAL
value: "5s"
- name: WORKER_HEARTBEAT_INTERVAL
value: "30s"
- name: WORKER_TASK_TIMEOUT
value: "15m"
- name: WORKER_CAPABILITIES
value: "build,sdlc"
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
livenessProbe:
exec:
command:
- test
- -f
- /usr/local/bin/rdev-worker
initialDelaySeconds: 5
periodSeconds: 60
# Claudebox sidecar - provides Claude Code execution via HTTP
- name: claudebox
image: ghcr.io/orchard9/rdev-claudebox:latest
imagePullPolicy: Always
env:
- name: PORT
value: "8080"
- name: WORKSPACE_DIR
value: "/workspace"
- name: GITEA_TOKEN
valueFrom:
secretKeyRef:
name: rdev-worker-credentials
key: gitea-token
optional: true
- name: GIT_USER
value: "rdev-worker"
- name: GIT_EMAIL
value: "worker@threesix.ai"
ports:
- name: http
containerPort: 8080
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2"
memory: "4Gi"
volumeMounts:
- name: workspace
mountPath: /workspace
- name: claude-config
mountPath: /root/.claude
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
volumes:
# EmptyDir for workspace - ephemeral per-pod
- name: workspace
emptyDir:
sizeLimit: 10Gi
# Shared Claude config volume for authentication
# Uses the same PVC as the claudebox statefulset
- name: claude-config
persistentVolumeClaim:
claimName: claudebox-claude-config
imagePullSecrets:
- name: ghcr-secret
---
# Secret for worker credentials
apiVersion: v1
kind: Secret
metadata:
name: rdev-worker-credentials
namespace: rdev
labels:
app.kubernetes.io/name: rdev-worker
app.kubernetes.io/part-of: rdev
type: Opaque
stringData:
# API key for workers to authenticate with rdev-api
# Create with: kubectl create secret generic rdev-worker-credentials --from-literal=api-key=<key> --from-literal=gitea-token=<token>
api-key: "placeholder-replace-me"
gitea-token: "placeholder-replace-me"
---
# Service for accessing worker metrics (optional)
apiVersion: v1
kind: Service
metadata:
name: rdev-worker
namespace: rdev
labels:
app.kubernetes.io/name: rdev-worker
app.kubernetes.io/part-of: rdev
spec:
selector:
app: rdev-worker
ports:
- port: 8080
name: claudebox
targetPort: 8080