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 kubectl configured
  • 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.

terminal
openssl rand -hex 32

2. 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}/callback

Set both the CLIENT_ID and CLIENT_SECRET for each provider you want to enable.

Warning

Ensure 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.

values.production.yaml
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.

values.production.yaml
api:
  env:
    PUBLIC_URL: "https://optio.example.com"

5. Configure Ingress

Enable ingress with TLS to expose Optio externally.

values.production.yaml
ingress:
  enabled: true
  hosts:
    - host: optio.example.com
  tls: true
  annotations:
    # Example for cert-manager
    cert-manager.io/cluster-issuer: letsencrypt-prod

6. Push Agent Images to a Registry

Build agent images and push them to a container registry accessible by your cluster.

terminal
# 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:latest
values.production.yaml
agent:
  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:

terminal
kubectl top nodes
# If this errors, install metrics-server:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

Full Production Values

Here is a complete example values.production.yaml combining all the above:

values.production.yaml
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: true

Install

terminal
helm install optio helm/optio \
  -f values.production.yaml \
  --namespace optio \
  --create-namespace

Upgrading

To upgrade an existing deployment:

terminal
# 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=3

Info

Database migrations run automatically when the API server starts. No manual migration step is needed during upgrades.

Performance Tuning

Once deployed, tune these settings based on your workload:

SettingDefaultNotes
OPTIO_MAX_CONCURRENT5Increase for clusters with more resources
maxPodInstances1/repoScale up for repos with high throughput
maxAgentsPerPod2/podIncrease if pods have sufficient CPU/memory
OPTIO_REPO_POD_IDLE_MS10 minIncrease to reduce cold starts for sporadic repos
OPTIO_PR_WATCH_INTERVAL30sIncrease to reduce GitHub API rate limit usage
maxTurnsCodingnullSet per-repo to limit agent cost and runtime

Troubleshooting

Pod won't start

terminal
# 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 optio

Agent fails with auth error

  • Verify CLAUDE_AUTH_MODE secret is set to api-key or oauth-token
  • For API key mode: ensure ANTHROPIC_API_KEY secret exists
  • For OAuth token mode: ensure CLAUDE_CODE_OAUTH_TOKEN secret exists
  • Check token validity via GET /api/auth/status

Tasks stuck in queued

  • Check concurrency limits: OPTIO_MAX_CONCURRENT and per-repo maxConcurrentTasks
  • Look for stuck tasks in provisioning or running state that may need manual cancellation
  • Check the API server logs for re-queue messages

OAuth login fails

  • Verify PUBLIC_URL matches the actual deployment URL
  • Ensure the OAuth callback URL is registered with the provider
  • Check for invalid_state errors, which indicate expired CSRF tokens (10 min TTL)

Teardown

terminal
helm uninstall optio -n optio

Warning

This removes all Optio deployments and services. Your external database and Redis data are preserved if you used managed services. Built-in PostgreSQL data will be lost.

Next Steps