Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/jonwiggins/optio/llms.txt

Use this file to discover all available pages before exploring further.

Production deployment uses the same Helm chart as local development, configured for external managed services, real OAuth authentication, TLS ingress, and a container registry for agent images.

Prerequisites

  • A Kubernetes cluster (EKS, GKE, AKS, or any conformant cluster)
  • Helm 3+ (helm version)
  • A managed PostgreSQL instance (e.g. RDS, Cloud SQL, Supabase, Neon)
  • A managed Redis instance (e.g. ElastiCache, Upstash, Redis Cloud)
  • A container registry for agent images (e.g. GHCR, ECR, Docker Hub)
  • At least one OAuth provider (GitHub, Google, or GitLab) with a registered application
  • metrics-server installed in the cluster
  • A domain name with DNS pointing to your cluster’s load balancer

Deployment

1

Generate an encryption key

Optio encrypts all secrets at rest with AES-256-GCM. Generate a key and keep it somewhere safe — if you lose it, stored secrets (API keys, OAuth tokens) cannot be decrypted.
openssl rand -hex 32
Store the output. You will pass it as --set encryption.key=<value> during install.
2

Push agent images to your registry

Build and push the agent image presets to a registry your cluster can pull from:
# Build all presets
./images/build.sh

# Tag and push (example using GHCR)
docker tag optio-base:latest ghcr.io/your-org/optio-agent-base:latest
docker tag optio-node:latest ghcr.io/your-org/optio-agent-node:latest
docker tag optio-python:latest ghcr.io/your-org/optio-agent-python:latest
docker tag optio-go:latest ghcr.io/your-org/optio-agent-go:latest
docker tag optio-rust:latest ghcr.io/your-org/optio-agent-rust:latest
docker tag optio-full:latest ghcr.io/your-org/optio-agent-full:latest

docker push ghcr.io/your-org/optio-agent-base:latest
# ... repeat for each preset
Set agent.imagePullPolicy to IfNotPresent or Always (not Never) so Kubernetes can pull from the registry.
3

Configure an OAuth provider

Register an OAuth application with at least one provider. Optio supports GitHub, Google, and GitLab.GitHub — go to Settings → Developer settings → OAuth Apps → New OAuth App:
  • Homepage URL: https://optio.example.com
  • Authorization callback URL: https://optio.example.com/api/auth/github/callback
Note the Client ID and Client Secret.
The callback URL must match API_PUBLIC_URL exactly, including the /api/auth/<provider>/callback path. If these do not match, OAuth login will fail with a redirect URI mismatch error.
4

Install the Helm chart

helm install optio helm/optio \
  --namespace optio \
  --create-namespace \
  --set encryption.key=$(openssl rand -hex 32) \
  --set postgresql.enabled=false \
  --set externalDatabase.url="postgres://user:pass@your-db-host:5432/optio" \
  --set redis.enabled=false \
  --set externalRedis.url="redis://your-redis-host:6379" \
  --set ingress.enabled=true \
  --set ingress.hosts[0].host=optio.example.com \
  --set auth.github.clientId=your-github-client-id \
  --set auth.github.clientSecret=your-github-client-secret \
  --set agent.image.repository=ghcr.io/your-org/optio-agent-base \
  --set agent.imagePullPolicy=IfNotPresent
Replace values with your actual database URL, Redis URL, domain, OAuth credentials, and agent image repository.
Do not pass --set auth.disabled=true in production. Optio requires OAuth authentication to be active. If auth.disabled is set, any user can access the deployment without logging in.
5

Set the GitHub token secret

Optio needs a GitHub token for PR watching, issue sync, and repository detection. After the API pod is running, add it via the web UI (Settings → Secrets) or directly:
# The setup wizard in the web UI will prompt for this on first run
# Navigate to: https://optio.example.com/setup
The GITHUB_TOKEN secret requires repo scope for private repositories and public_repo for public ones.
6

Verify the deployment

Check that all pods are running:
kubectl get pods -n optio
Expected output shows optio-api-*, optio-web-*, and (if using in-cluster databases) optio-postgres-* and optio-redis-* pods all in Running state.Open https://optio.example.com — you should be redirected to the login page.

Production checklist

Review each item before going live:
#ItemNotes
1Encryption key generatedopenssl rand -hex 32; store it securely
2OAuth provider configuredAt least one of GitHub, Google, or GitLab
3Auth bypass disabledauth.disabled must be false or unset
4External PostgreSQLpostgresql.enabled=false + externalDatabase.url
5External Redisredis.enabled=false + externalRedis.url
6Public URLs setAPI_PUBLIC_URL and WEB_PUBLIC_URL match your domain
7Ingress with TLSingress.enabled=true with cert-manager or manual TLS
8Agent image in registryagent.imagePullPolicy=IfNotPresent or Always
9GitHub token secret setRequired for PR watching, issue sync, repo detection
10Resource limits tunedAdjust api.resources and agent PVC size for your workload
11metrics-server installedRequired for resource usage display in the cluster view

TLS with cert-manager

If cert-manager is installed in your cluster, enable automatic certificate provisioning:
helm upgrade optio helm/optio -n optio --reuse-values \
  --set ingress.certManager.enabled=true \
  --set ingress.certManager.clusterIssuer=letsencrypt-prod
For manual TLS certificate management, configure the ingress.tls field directly in a values file:
ingress:
  enabled: true
  tls:
    - secretName: optio-tls
      hosts:
        - optio.example.com

RBAC requirements

The Helm chart creates a ServiceAccount and Role for the API server automatically. The API server needs these permissions to manage agent pods:
  • pods: get, list, watch, create, delete
  • pods/exec: create (for running agents in pods)
  • pods/log: get
  • secrets: get, list, create, update, delete
  • persistentvolumeclaims: get, list, create, delete
  • services: get, list, create, delete
  • events: get, list, watch
A separate ClusterRole covers read access to nodes, namespaces, and metrics for the cluster health view. Do not remove or restrict these permissions — the API server will fail to provision agent pods.

Updating

To apply new configuration changes or upgrade to a newer version:
# Apply changes while preserving existing values
helm upgrade optio helm/optio -n optio --reuse-values
To trigger a rolling restart of the API and web servers (e.g. after updating a secret or environment variable):
kubectl rollout restart deployment/optio-api deployment/optio-web -n optio

Troubleshooting

  • Verify that the callback URL registered with the OAuth provider exactly matches {API_PUBLIC_URL}/api/auth/<provider>/callback
  • Set API_PUBLIC_URL explicitly in your Helm values if it is not being inferred correctly
  • Check for trailing slashes or http vs https mismatches
  • Confirm the agent image is pushed to your registry and the tag is correct
  • Check that imagePullSecrets is configured if your registry requires authentication
  • Verify agent.imagePullPolicy is IfNotPresent or Always (not Never)
  • Confirm externalDatabase.url is formatted correctly: postgres://user:pass@host:5432/dbname
  • Test connectivity from within the cluster: kubectl run -it --rm debug --image=postgres:16 --restart=Never -n optio -- psql "$DATABASE_URL"
  • Check that the database allows connections from the cluster’s IP range
  • Increase resource limits for agent pods via the image preset or Helm values (agent.pvc.size, API resource limits)
  • Check pod_health_events via the cluster view in the web UI for crash history
  • The cleanup worker automatically fails tasks on dead pods and recreates pods on the next task

Build docs developers (and LLMs) love