Skip to content

Install with deploy.yaml

The raw manifest path for the control plane. Use this when you need a plain YAML file under GitOps. Use exo-install for the control plane, operator, and CRDs, with a separate database migration step.

deploy.yaml is a single-file manifest for the Industric control plane: a Namespace, a Secret, a ConfigMap, and a Deployment plus Service for exo-app. Control plane only. To bring agents online you still need the operator and CRD steps from exo-install, or the manifests & Helm chart.

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.
Want everything at once
Use exo-install. It installs the control plane, operator, and CRDs. Database migrations are a separate step before startup.

Prerequisites

  • Kubernetes 1.27+ with cluster-admin access.
  • An accessible Postgres 16 instance with a database for Industric.
  • A way to expose ClusterIP services: ingress controller, service mesh, or port-forward for a demo.

Secrets

The stock file ships the Secret with changeme-* placeholders for all three values. Generate real ones before applying. None are recoverable if lost, so store them in a vault.

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

Required edits

Before you apply
  • Replace the changeme-* secrets. The stock Secret ships placeholder values for EXO_JWT_SECRET, EXO_ENCRYPTION_KEY, and EXO_DATABASE_DSN. Set all three. The backend refuses to boot if EXO_ENCRYPTION_KEY isn't a real 32-byte key.
  • Pick your namespace. Every object ships in namespace exo. Rename it (or leave it) consistently across the Namespace, Secret, ConfigMap, Service, and Deployment.

Apply

  1. Set the exo-app Deployment to replicas: 0 in deploy.yaml, then apply it.
  2. Run the target image's database migration with the same configuration. Stop if it fails.
  3. After success, restore the desired replica count and apply again.
terminal· bash
kubectl apply -f deploy.yaml
kubectl -n exo rollout status deploy/exo-app

Reach the app

terminal· bash
kubectl port-forward -n exo svc/exo-app 9092:9092

Sign up at localhost:9092. The first account becomes the org admin. From there, invite your team, mint a deployment token, and connect a cluster via the Industric 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:
12 - app.exo.example.com
13 secretName: exo-tls
14 rules:
15 - host: app.exo.example.com
16 http:
17 paths:
18 - path: /
19 pathType: Prefix
20 backend:
21 service:
22 name: exo-app
23 port:
24 number: 9092
WebSocket-aware ingress
The operator's control connection and the dashboard shell channel are both WebSockets. For NGINX, set proxy_read_timeout and ensure HTTP/1.1 upgrades are allowed.