§02 — Exo Control Plane

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.

5 min read·Set by Exo Editorial·v0.3.0 Beta

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 ClusterIP services — 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.

terminal· bash
1openssl rand -hex 16 # → EXO_ENCRYPTION_KEY (exactly 32 bytes)
2openssl rand -base64 48 # → EXO_JWT_SECRET
deploy.yaml · exo-secrets.stringData· yaml
1stringData:
2 EXO_JWT_SECRET: "<openssl rand -base64 48>"
3 EXO_ENCRYPTION_KEY: "<openssl rand -hex 16>" # must be exactly 32 bytes
4 EXO_DATABASE_DSN: "postgres://exo:<password>@<host>:5432/exo?sslmode=require"

Required edits

Apply

terminal· bash
1kubectl apply -f deploy.yaml
2kubectl -n exo rollout status deploy/exo-app

The 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

terminal· bash
1kubectl port-forward -n exo svc/exo-app 9092:9092
2# → http://localhost:9092

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

ingress.yaml· yaml
1apiVersion: networking.k8s.io/v1
2kind: Ingress
3metadata:
4 name: exo
5 namespace: exo
6 annotations:
7 cert-manager.io/cluster-issuer: letsencrypt
8spec:
9 ingressClassName: nginx
10 tls:
11 - hosts: [app.exo.example.com]
12 secretName: exo-tls
13 rules:
14 - host: app.exo.example.com
15 http:
16 paths:
17 - path: /
18 pathType: Prefix
19 backend:
20 service:
21 name: exo-app
22 port:
23 number: 9092