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.MCP_BASE_URL is the address a runner advertises to its own sidecars for MCP callbacks, and it defaults to RUNNER_BASE_URL when unset. In a multi-replica StatefulSet, template it per pod the same way as RUNNER_BASE_URL: pinning it to a single replica’s hostname across all pods misroutes every other replica’s sidecar tool calls.
StatefulSet and headless service, pods get stable DNS names:
<runner-0>.<runner-service>.<cluster-domain>:7070<runner-1>.<runner-service>.<cluster-domain>:7070<runner-2>.<runner-service>.<cluster-domain>: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 include<runner-3>.<runner-service>.<cluster-domain>: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, gated behind a bearer token: set METRICS_AUTH_TOKEN on the conductor Deployment and the runner StatefulSet, or every scrape gets a 401 Unauthorized. Create a ServiceMonitor if you’re using the Prometheus Operator, pointing bearerTokenSecret at that same token: