unoverse CLI the second, and these runbooks cover the third:
- Provision β your ground (
infra/digitaloceanorinfra/aws) creates the VM, load balancer, TLS certificate, firewall, Postgres, and Redis, and renders the complete production configuration../unoverse groundprefills its input file from your cloud CLI. - Deploy β
unoverse deploy initthe first time,unoverse deployafter that. - Operate β database, hardening, health, restarts: the runbooks below.
Provision (Terraform)
Sizes
size in terraform.tfvars scales the box and the stores, never the topology (all sizes are single-VM). When multi-VM Active-Active arrives it will scale the app tier only: UMAP stays one shared service (UMAP_SERVICE_URL), because spatial coordinates are only comparable through the same trained model instance.
External Dependencies
Supported Platforms
- Cloud grounds: DigitalOcean (
infra/digitalocean), AWS (infra/aws) - On-prem: any Ubuntu 22.04+ / Debian 12 VM β you own firewall and TLS, then Deploy and Operate are identical
Deploy (the CLI)
init stays available on its own for re-runs: deploy db, deploy test.
The CLI reads the deploy target from your groundβs rendered configuration and generates a temporary Ansible inventory on every run, so there is no inventory file to maintain.
Your own work (nodes, design, prompts) never rides a deploy: it arrives via unoverse update (git), the Marketplace (per item, database-driven), or Studio publish.
Operate (the runbooks)
Logs need no runbook: Dozzle runs by default at
http://<VM_IP>:8080 (admin-IP-only via the cloud firewall), streams straight from the Docker socket, and stores nothing. Log growth is capped by json-file rotation (10 MB Γ 3 per service) in docker-compose.yml. Enterprise ships logs to its own SIEM by pointing the Docker logging driver there instead.
Environment: One File You Write, One You Donβt
.env is yours β local development only. Copy .env.example, set localhost Postgres, Redis, your OpenAI key, and your OIDC values (or AUTH_ENABLED=false). Docker compose reads it automatically. Gitignored.
Production configuration is not a file you touch. Your terraform.tfvars is the single input; everything downstream is machine-managed:
.env.production (gitignored) as a deploy artifact β unoverse deploy re-renders it from your applied ground whenever itβs missing. Two things are worth knowing about it, and only two:
- It holds the master
CREDENTIAL_ENCRYPTION_KEY. Keep a safe copy with your database backups: a database backup is unreadable without it. - Never edit it. To change any production value, edit terraform.tfvars,
terraform apply, delete the file, and redeploy.
DOMAIN drives Canvas URLs:
When DOMAIN=yourdomain.com is set, docker-compose.yml automatically derives:
VITE_API_URL=https://api.yourdomain.comVITE_SERVER_WS_URL=wss://api.yourdomain.com
DOMAIN is unset (local dev), set API_URL=http://localhost:4105 in .env β Canvas calls the platformβs public listener (unoverse :4105) directly.
Prerequisites
- Terraform 1.5+ and your cloud CLI (doctl or aws) on your machine
- Ansible installed locally (
pip install ansible) - DOCR token for pulling images (from your Unoverse admin)

