Install with deploy.yaml
The raw manifest path for the control plane. Use this when you need a plain YAML file under GitOps. For a full system install — control plane, operator, and CRDs in one step — use exo-install instead.
deploy.yaml is a single-file manifest for the Exo control plane: a Namespace, a Secret, a ConfigMap, and a Deployment + Service for exo-app. It installs the control plane only — you still need the exo-install operator and CRD steps, or the Helm chart, to bring agents online in a cluster.
When to use this
- You manage cluster state with Argo CD, Flux, or a kustomize tree and want the raw manifest checked in.
- You need to diff and review every RBAC or Secret change before it lands.
- You only need the control plane and will wire up the operator separately.
Prerequisites
- Kubernetes 1.27+ with cluster-admin access.
- An accessible Postgres 16 instance with a database for Exo.
- A way to expose
ClusterIPservices — ingress controller, service mesh, or port-forward for a demo.
Secrets
Generate the two required secrets before applying. Neither can be recovered if lost — store them in a vault.
1openssl rand -hex 16 # → EXO_ENCRYPTION_KEY (exactly 32 bytes)2openssl rand -base64 48 # → EXO_JWT_SECRET1stringData:2 EXO_JWT_SECRET: "<openssl rand -base64 48>"3 EXO_ENCRYPTION_KEY: "<openssl rand -hex 16>" # must be exactly 32 bytes4 EXO_DATABASE_DSN: "postgres://exo:<password>@<host>:5432/exo?sslmode=require"Required edits
Apply
1kubectl apply -f deploy.yaml2kubectl -n exo rollout status deploy/exo-appThe container runs database migrations at boot and won't serve traffic until they complete. If the rollout stalls, check the pod logs for migrate: dirty database — that means a prior version failed mid-migration and needs manual repair.
Reach the app
1kubectl port-forward -n exo svc/exo-app 9092:90922# → http://localhost:9092Sign up at localhost:9092 — the first account becomes the organisation's admin. From there, invite your team, mint a deployment token, and connect a cluster via the Exo Operator.
Ingress + TLS
The service is plain HTTP on port 9092. Terminate TLS at the ingress and point the upstream at the exo-app ClusterIP.
1apiVersion: networking.k8s.io/v12kind: Ingress3metadata:4 name: exo5 namespace: exo6 annotations:7 cert-manager.io/cluster-issuer: letsencrypt8spec:9 ingressClassName: nginx10 tls:11 - hosts: [app.exo.example.com]12 secretName: exo-tls13 rules:14 - host: app.exo.example.com15 http:16 paths:17 - path: /18 pathType: Prefix19 backend:20 service:21 name: exo-app22 port:23 number: 9092