This is a self-hosting guide. The hosted product at https://www.orcapods.ai needs none of this — sign in and go.
Architecture on Kubernetes
Key points:- Conductors →
Deployment+HPA(stateless, scale freely) - Runners →
StatefulSet+headless Service(stable pod DNS = stableRUNNER_BASE_URL) - Sidecars → additional containers inside each runner pod
- Ingress → nginx with
proxy_buffering offfor SSE
Conductor Deployment
Runner StatefulSet
Runners must have stable DNS names so conductors can route sessions to them.StatefulSet and headless service, pods get stable DNS names:
runner-0.runners.orca.svc:7070runner-1.runners.orca.svc:7070runner-2.runners.orca.svc:7070
RUNNER_URLS on the conductor.
Secrets
VirtualFS Strict Mount Configuration
When deploying the standalone VirtualFS service (orca/vfs) to Kubernetes, the strict mount model requires explicit backend configuration. Do NOT use --profile dev in production — the dev profile uses in-process RAM and cannot persist data across pod restarts.
Required environment variables for the prod profile:
If these are missing or the bucket is unreachable at pod startup, the affected mounts surface as
unavailable in GET /vfs/mounts. The server still passes /healthz — liveness checks are independent of mount status. Use the VirtualFS smoke script (scripts/vfs-smoke.sh) in a post-deploy readiness check to assert all expected mounts are ready before traffic is sent.
Ingress with SSE Support
Updating Runner Count
When you scale the StatefulSet, update the conductor’sRUNNER_URLS to include the new pod DNS names. The safest approach:
- Scale the StatefulSet:
kubectl scale statefulset runner --replicas=4 -n orca - Wait for the new pod to be ready:
kubectl rollout status statefulset runner -n orca - Update the conductor
Deploymentenv to includerunner-3.runners.orca.svc:7070 - Roll out the conductor:
kubectl rollout restart deployment conductor -n orca
Namespace and RBAC
Monitoring Integration
Both conductor and runner expose/metrics in Prometheus text format. Create a ServiceMonitor if you’re using the Prometheus Operator: