Install with exo-install
The recommended path. One binary applies the CRDs, the operator, and the platform through your own kubectl, with pre-flight checks and generated secrets.
exo-install installs the whole platform. The manifests are embedded in the binary and applied through your existing kubectl, so your kubeconfig auth (exec plugins, OIDC, cloud IAM) works unchanged. It never talks to the API server directly; it runs kubectl apply, so dry-runs, RBAC, and audit behave exactly as they do for your own manifests.
What exo-install does
It installs three layers in dependency order: the six autonomic.sh CRDs, the autonomic-manager operator (Deployment, RBAC, admission webhook), and the platform (backend/UI Deployment, Service, Secret, ConfigMap, and an optional in-cluster Postgres). The embedded manifests are pinned copies derived from the operator manifests under exo/exo-install/manifests/ and the repo-root deploy.yaml. Defaults point at the published images: docker.io/adaptivelive/autonomic-manager for the operator and docker.io/adaptivelive/exo (pinned to the installer's own release tag) for the platform. Any secret you don't supply is generated.
Set EXO_ENCRYPTION_KEY
EXO_ENCRYPTION_KEY is the 32-byte AES-256 root key that wraps every encrypted column, and the backend won't start without it. The installer auto-generates one when you don't pass --encryption-key (or leave the interactive prompt blank), then prints it once after install:
⚠ SAVE YOUR ENCRYPTION KEY — back it up now EXO_ENCRYPTION_KEY=4f3c2a9e8b7d6c5a4f3c2a9e8b7d6c5aCopy that value somewhere safe immediately. To supply your own instead:
exo-install install --yes --encryption-key "$(openssl rand -hex 16)"
Commands
1(none) Launch the guided full-terminal installer2precheck Verify toolchain, cluster reachability, and RBAC (alias: check)3install Install CRDs + operator + platform (alias: apply, up)4crds Install only the six autonomic CRDs5operator Install CRDs + operator (manager, RBAC, webhook)6platform Install only the backend/UI (+ optional Postgres)7render Print rendered manifests to stdout, apply nothing (alias: template)8config Write a config file via the interactive wizard9uninstall Remove selected components in reverse order (alias: down)10version Print the installer versioninstall runs the pre-flight checks first unless you pass --skip-precheck. Configuration resolves in three layers, each overriding the last: built-in defaults → --config file → CLI flags.
Pre-flight checks
exo-install precheck validates the environment before you touch the cluster. Hard failures abort the install; advisory ones only warn.
1Binaries kubectl (required) · helm (required with --helm) · docker, git (advisory)2Cluster current context set (required) · API reachable via cluster-info (required)3 server version (advisory)4RBAC can-i create: customresourcedefinitions, clusterroles,5 namespaces, deployments (advisory — warns, does not block)Interactive mode
Run it with no arguments for a guided full-terminal installer: arrow-key menus, inline validation, masked secret entry. It walks namespaces and images → database choice → secrets & operator mode → cluster connection → component selection → pre-flight → plan → apply.
exo-install
Scripted install
For CI or a repeatable runbook, drive it by subcommand and flags:
exo-install precheck
exo-install install --yes
exo-install install --dry-run
--yes skips confirmation prompts; --dry-run sends kubectl apply --dry-run=server so the API server validates without mutating. --timeout (default 5m) bounds each rollout wait.
Installing individual pieces
Each component has its own subcommand, useful for split-cluster topologies:
exo-install crds
exo-install operator --managed --base-url https://exo.example.com
exo-install platform --namespace exo --image adaptivelive/exo:v0.4.8
exo-install render crds | kubectl apply -f -
What gets created
CRDs: two namespaced resources in group autonomic.sh/v1alpha1: agents and tools. The installer waits for each to report established before moving on.
1ServiceAccount/autonomic-manager2ClusterRole + ClusterRoleBinding/autonomic-manager (CRDs, deployments, pods/exec,3 secrets, leases, webhooks, RBAC)4Service/autonomic-manager 443 webhook · 8080 metrics · 8081 probes · 8082 invoke5Deployment/autonomic-manager --leader-elect, replicas=1, non-root6ValidatingWebhookConfiguration/autonomic-pods-exec (pods/exec + tool admission;7 omitted with --webhook=false)1Secret/exo-secrets EXO_ENCRYPTION_KEY · EXO_JWT_SECRET · EXO_DATABASE_DSN · EXO_CLAUDE_API_KEY2ConfigMap/exo-config EXO_PORT=9092 · EXO_JWT_EXPIRY3Service/exo-app 9092/TCP, type ClusterIP (default)4Deployment/exo-app replicas=2, /api/health probes, rolling update5StatefulSet/exo-postgres postgres:16-alpine + 10Gi PVC (omitted with --postgres=false)Flag reference
Connection & execution. These control kubectl and how the install runs.
1--kubeconfig <path> kubeconfig file (default: $KUBECONFIG / ~/.kube/config)2--context <name> kube-context (default: current-context)3--dry-run server-side validate, no mutations4--config <file> load config from JSON (flags still override)5--interactive prompt for config6--skip-precheck skip pre-flight checks (not recommended)7--yes assume yes to prompts8--timeout <dur> per-rollout wait (default: 5m)9--helm install the operator via its Helm chart10--helm-chart <path|ref> chart location (required with --helm)Operator. The autonomic-manager deployment.
1--operator-namespace autonomic-system2--manager-image docker.io/adaptivelive/autonomic-manager:v0.3.13--manager-pull-policy IfNotPresent4--operator-replicas 15--managed false (phone home to --base-url)6--base-url https://exo.adaptive.live7--webhook true (pods/exec + tool admission webhook)8--webhook-failure-policy Fail (or Ignore)9--webhook-timeout 5 (seconds)Platform. The exo-app backend/UI deployment.
1--namespace exo2--image docker.io/adaptivelive/exo:latest3--pull-policy IfNotPresent4--replicas 25--service-type ClusterIP (or NodePort, LoadBalancer)6--jwt-expiry 24h7--jwt-secret "" (auto-generated if blank)8--encryption-key "" (EXO_ENCRYPTION_KEY, 32 bytes; auto-generated + printed if blank)9--claude-api-key "" (platform-default Anthropic key, base64'd; optional)Database. In-cluster Postgres or an external instance.
1--postgres true (deploy in-cluster Postgres StatefulSet)2--db-dsn "" (external DSN, required when --postgres=false)3--pg-user exo4--pg-password "" (auto-generated if blank)5--pg-db exo6--pg-storage 10Gi (PVC size)Generated secrets
Any secret you don't supply is generated at apply time and written into the cluster Secrets, never logged:
1EXO_ENCRYPTION_KEY 32 hex chars when --encryption-key is blank → Secret/exo-secrets (SAVE IT)2EXO_JWT_SECRET 64 hex chars when --jwt-secret is blank → Secret/exo-secrets3POSTGRES_PASSWORD 36 hex chars when --postgres and no pw → Secret/exo-postgres4EXO_DATABASE_DSN derived from the in-cluster Postgres → Secret/exo-secretsBring your own database
Skip the bundled Postgres and point the platform at a managed instance:
exo-install install --postgres=false \--db-dsn "host=db.example.com user=exo dbname=exo sslmode=require"
Config files
Capture every knob in a JSON file and reuse it; flags still override the file.
exo-install config -o exo-install.json
exo-install install --config exo-install.json --namespace staging
1{2 "operatorNamespace": "autonomic-system",3 "managerImage": "docker.io/adaptivelive/autonomic-manager:v0.3.1",4 "operatorManaged": false,5 "operatorBaseURL": "https://exo.adaptive.live",6 "webhookEnabled": true,7 "platformNamespace": "exo",8 "platformImage": "docker.io/adaptivelive/exo:latest",9 "platformReplicas": 2,10 "serviceType": "ClusterIP",11 "jwtExpiry": "24h",12 "postgres": true,13 "postgresStorage": "10Gi"14}Helm for the operator
Uninstall
Removes components in reverse order: platform → operator → CRDs.
exo-install uninstall