Production Deployment
This guide walks through deploying Optio to a production Kubernetes cluster. Optio ships as a Helm chart that deploys the API server, web dashboard, and supporting infrastructure.
Prerequisites
- A Kubernetes cluster (1.24+) with
kubectlconfigured - Helm 3+
- Managed PostgreSQL instance
- Managed Redis instance
- A domain name with DNS configured
- TLS certificate (or cert-manager for automatic provisioning)
Deployment Checklist
Work through each item before going live. Every item marked as required must be completed.
1. Generate an Encryption Key
All secrets stored in the database are encrypted with AES-256-GCM. Generate a key and keep it safe — losing it means losing access to all stored secrets.
openssl rand -hex 322. Configure OAuth
Set up at least one OAuth provider for user authentication. Supported providers: GitHub, Google, and GitLab. Register your OAuth application with the callback URL:
https://optio.example.com/api/auth/{provider}/callbackSet both the CLIENT_ID and CLIENT_SECRET for each provider you want to enable.
Warning
OPTIO_AUTH_DISABLED is NOT set (or is set to false) in production. Leaving auth disabled exposes the entire system without authentication.3. Use External Databases
The built-in PostgreSQL and Redis instances are single-node with no replication. Always use managed services in production.
postgresql:
enabled: false
externalDatabase:
url: "postgresql://user:pass@your-rds-host:5432/optio"
redis:
enabled: false
externalRedis:
url: "redis://your-elasticache-host:6379"4. Set the Public URL
PUBLIC_URL must match the actual deployment URL. This is used for OAuth callback URLs, webhook URLs, and the web app's API connection.
api:
env:
PUBLIC_URL: "https://optio.example.com"5. Configure Ingress
Enable ingress with TLS to expose Optio externally.
ingress:
enabled: true
hosts:
- host: optio.example.com
tls: true
annotations:
# Example for cert-manager
cert-manager.io/cluster-issuer: letsencrypt-prod6. Push Agent Images to a Registry
Build agent images and push them to a container registry accessible by your cluster.
# Build all presets (base, node, python, go, rust, full)
./images/build.sh
# Tag and push to your registry
docker tag optio-agent-node:latest registry.example.com/optio-agent-node:latest
docker push registry.example.com/optio-agent-node:latestagent:
imagePullPolicy: IfNotPresent
# or: Always (to pick up image updates on every task)7. Set Up a GitHub Token
A GitHub personal access token is required for PR watching, issue synchronization, and repository language detection. Add it as a secret in the Optio dashboard after first login, or set it via the setup wizard.
8. Tune Resource Limits
Adjust pod resource requests and limits based on your expected agent workload. Agents can be memory-intensive, especially for large repositories.
9. Install metrics-server
Optio's cluster monitoring page requires the Kubernetes metrics-server to display resource usage data. Most managed Kubernetes services include it, but verify:
kubectl top nodes
# If this errors, install metrics-server:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yamlFull Production Values
Here is a complete example values.production.yaml combining all the above:
api:
replicas: 2
env:
PUBLIC_URL: "https://optio.example.com"
web:
replicas: 2
env:
NEXT_PUBLIC_API_URL: "https://optio.example.com/api"
NEXT_PUBLIC_WS_URL: "wss://optio.example.com"
encryption:
key: "<your-64-char-hex-key>"
postgresql:
enabled: false
externalDatabase:
url: "postgresql://user:pass@your-db:5432/optio"
redis:
enabled: false
externalRedis:
url: "redis://your-redis:6379"
auth:
github:
clientId: "your-github-oauth-client-id"
clientSecret: "your-github-oauth-client-secret"
agent:
imagePullPolicy: IfNotPresent
ingress:
enabled: true
hosts:
- host: optio.example.com
tls: trueInstall
helm install optio helm/optio \
-f values.production.yaml \
--namespace optio \
--create-namespaceUpgrading
To upgrade an existing deployment:
# Upgrade with new values or chart version
helm upgrade optio helm/optio \
-f values.production.yaml \
--namespace optio
# Or reuse existing values and only change specific settings
helm upgrade optio helm/optio \
--namespace optio \
--reuse-values \
--set api.replicas=3Info
Performance Tuning
Once deployed, tune these settings based on your workload:
| Setting | Default | Notes |
|---|---|---|
| OPTIO_MAX_CONCURRENT | 5 | Increase for clusters with more resources |
| maxPodInstances | 1/repo | Scale up for repos with high throughput |
| maxAgentsPerPod | 2/pod | Increase if pods have sufficient CPU/memory |
| OPTIO_REPO_POD_IDLE_MS | 10 min | Increase to reduce cold starts for sporadic repos |
| OPTIO_PR_WATCH_INTERVAL | 30s | Increase to reduce GitHub API rate limit usage |
| maxTurnsCoding | null | Set per-repo to limit agent cost and runtime |
Troubleshooting
Pod won't start
# Check pod status and events
kubectl get pods -n optio
kubectl describe pod <pod-name> -n optio
# Verify agent images exist
kubectl get pods -n optio -o jsonpath='{.items[*].spec.containers[*].image}'
# Check PVC availability
kubectl get pvc -n optioAgent fails with auth error
- Verify
CLAUDE_AUTH_MODEsecret is set toapi-keyoroauth-token - For API key mode: ensure
ANTHROPIC_API_KEYsecret exists - For OAuth token mode: ensure
CLAUDE_CODE_OAUTH_TOKENsecret exists - Check token validity via
GET /api/auth/status
Tasks stuck in queued
- Check concurrency limits:
OPTIO_MAX_CONCURRENTand per-repomaxConcurrentTasks - Look for stuck tasks in
provisioningorrunningstate that may need manual cancellation - Check the API server logs for re-queue messages
OAuth login fails
- Verify
PUBLIC_URLmatches the actual deployment URL - Ensure the OAuth callback URL is registered with the provider
- Check for
invalid_stateerrors, which indicate expired CSRF tokens (10 min TTL)
Teardown
helm uninstall optio -n optioWarning