Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.definite.app/llms.txt

Use this file to discover all available pages before exploring further.

This page is a runbook designed to be read by an AI agent (Claude Code, Cursor, Windsurf, or similar). The agent reads this page, asks the human user the intake questions below in order, and then executes the install against their cloud account. If you are a human reading this directly, you probably want the cloud-specific guide: AWS, GCP, or Azure. Come back here when you’d rather have an agent drive.

Quick-start: paste this into your agent

Open a fresh session in Claude Code (or Cursor, Windsurf, etc.) in an empty working directory, and paste:
I want to install on-prem Definite. Fetch the runbook at
https://docs.definite.app/on-prem/agent-setup.md and walk me through
it step by step. Ask me one question at a time, wait for my answer,
and do not skip the preflight checks.
That’s it. The agent will fetch this page, ask the questions in the Intake section, then drive Phases 2-5 against your cloud account.
For agents: every page on this site is also published as plain Markdown by appending .md to the URL. Use the .md URL when you fetch a doc — it’s smaller, has no JSX components, and is easier to parse. So /on-prem/aws is at https://docs.definite.app/on-prem/aws.md, /on-prem/gcp at https://docs.definite.app/on-prem/gcp.md, and so on.
If your agent supports MCP, also add the Definite docs as a source so it can pull in the per-cloud guides on demand: claude mcp add --transport http definite-docs https://docs.definite.app/mcp.

For the agent: how to use this page

You are an AI coding agent helping a human install on-prem Definite into their own cloud account. Read this entire page before asking your first question. Follow these rules:
  1. Ask one question at a time. Do not batch the intake questions. Wait for the human’s answer before moving on.
  2. Run real commands against the human’s cloud account. Do not just print them. Use your shell tool. Confirm before any destructive operation (delete, drop, force-destroy).
  3. Never invent values. If the human hasn’t given you a region, project ID, hostname, password, or credential, ask. Placeholders like <your-region> must be replaced before any command runs.
  4. Capture every value into a single config.yaml as you go. Don’t ask the human to write the file; you write it, show it to them, and confirm before definite init.
  5. Run definite doctor before definite init. Do not pass --skip-preflight.
  6. Hand off to the per-cloud guide for the long shell sequences. Phase 2 below tells you which page to fetch.
  7. Stop and escalate to a human at Definite (hello@definite.app) if: the cloud lacks a permission you need, an LLM provider rejects the model, definite doctor fails for a reason you can’t fix in three tries, or the human asks for production support beyond install.

Phase 0: Confirm the agent’s environment

Before asking the human anything, verify your own tooling. Run, in parallel:
which kubectl helm
kubectl version --client 2>/dev/null
helm version --short 2>/dev/null
You need kubectl 1.28+ and helm 3.12+. If either is missing, install them before continuing. The cloud CLI (aws, gcloud, or az) is checked in Phase 2 once you know which cloud.

Phase 1: Intake

Ask the human these questions in order. Capture each answer into a working scratchpad you can refer back to in later phases.

Q1. Which cloud?

“Which cloud are you installing on: AWS, GCP, or Azure?”
Record as CLOUD. This drives every subsequent decision.
If CLOUD =Per-cloud guide to fetch in Phase 2ClusterPostgresObject storeDefault LLM
AWS/on-prem/awsEKSRDS Postgres 15S3Bedrock
GCP/on-prem/gcpGKE (Autopilot)Cloud SQL Postgres 15GCS (HMAC)Vertex AI
Azure/on-prem/azureAKSPostgres Flexible Server 15Blob StorageAzure OpenAI
Azure is currently a preliminary guide. If the human picks Azure, tell them this is not yet validated end to end, and recommend they email hello@definite.app to be a design partner before proceeding.

Q2. Environment

“Is this a demo / pilot install (you’ll throw it away in a few weeks), or a production install (real users, real data)?”
Record as ENV ∈ {demo, prod}. This changes a handful of defaults:
SettingDemoProduction
HA databasessingle-AZmulti-AZ / regional
Deletion protectionoffon
Hostnamenip.ioreal DNS A/CNAME
TLSLet’s Encrypt staging is fineLet’s Encrypt prod
Backupsnonedaily snapshots
Lakehouse PVC size50Gisize to expected data + 2x

Q3. Hostname

“What hostname should Definite be reachable at? For demos, I can build a nip.io hostname from the load balancer IP after we provision. For production, you’ll want a real DNS record like definite.acme.com.”
Record as HOSTNAME. If ENV = demo, defer this question until after the LB IP exists in Phase 2.
Some OAuth providers (Google, Slack, HubSpot) reject nip.io redirect URIs. If the human is going to integrate any of those, push them to a real DNS record now.

Q4. Authentication

“How should users sign in: local auth (email + password, simplest), or OIDC SSO (Google Workspace, Okta, Entra ID, etc.)?”
Record as AUTH ∈ {local, oidc}. If AUTH = oidc, also ask:
“Which OIDC provider? I’ll need the issuer URL, client ID, and client secret.”
If they want Google Workspace SSO specifically, point them at /on-prem/sso for the OAuth client setup, and continue.

Q5. LLM provider

“Which LLM provider should Fi use?”
CLOUDDefaultAlternatives
AWSBedrock (IRSA, no static creds)Anthropic direct, Azure OpenAI, Vertex
GCPVertex AI (Workload Identity, no static creds)Anthropic direct, Bedrock, Azure OpenAI
AzureAzure OpenAIAnthropic direct, Bedrock, Vertex
Record as LLM_PROVIDER. For Bedrock or Vertex, confirm the human has model access enabled in their account for the Claude model they want.

Q6. Region

“Which region? Pick whatever is closest to your users / source data. If you’re not sure, [recommend their cloud’s most-popular region].”
Record as REGION. Cross-check that the chosen LLM model is available in this region (Bedrock and Vertex availability varies).

Q7. Existing infrastructure to reuse

“Are you starting fresh, or do you have existing infrastructure you want me to reuse: an existing Kubernetes cluster, an existing Postgres database, or an existing object-store bucket?”
Most installs are greenfield. If the human says they want to reuse something, capture the connection details and note them for Phase 2: you’ll skip provisioning that resource but still need it in config.yaml.

Q8. Naming

“What name prefix should I use for the resources I create? Default is definite.”
Record as NAME_PREFIX. This becomes part of cluster name, bucket name, DB name, etc.

Phase 2: Provision cloud infrastructure

You now have enough information to provision. Fetch the per-cloud guide for CLOUD and execute Phase 1 (“Provision …”) of that guide, substituting the answers from Intake.
CLOUDFetch (use the .md URL) and follow
AWS/on-prem/aws.md — Phase 1 (Terraform module)
GCP/on-prem/gcp.md — Phase 1 (gcloud sequence)
Azure/on-prem/azure.md — Phase 1 (az sequence)
A few rules that apply across all three:
  • Confirm the cloud CLI is authenticated before running anything. aws sts get-caller-identity / gcloud config list account / az account show. If the human isn’t logged in, ask them to authenticate; do not try to authenticate as them.
  • Capture every output you’ll need for config.yaml as you go (cluster name, DB connection string, bucket name, access keys, service-account emails). Don’t make the human re-run commands to find them.
  • Get explicit confirmation before any command that costs money (cluster create, RDS create, Cloud SQL create) or that writes IAM bindings.
  • Provisioning takes 20-40 minutes, mostly the managed Kubernetes cluster. Tell the human that up front. Run independent commands in parallel where possible.
When Phase 1 of the per-cloud guide is done, return here for Phase 3.

Phase 3: Assemble config.yaml

Open a new file config.yaml in the human’s working directory and fill it in from your scratchpad. The shape is the same across clouds; only object_store, lakehouse.storage.storage_class_name, and llm change. A canonical template (replace every <...> with a real value from Intake or Phase 2):
deployment:
  name: <NAME_PREFIX>
  namespace: <NAME_PREFIX>
  hostname: <HOSTNAME>                 # nip.io for demo, real DNS for prod
  tls: cert_manager

postgres:
  url: postgres://<user>:${POSTGRES_PASSWORD}@<host>:5432/<db>

object_store:
  # type: s3 | gcs | azure
  # See the per-cloud guide for the exact credentials shape.

lakehouse:
  prefix: lake/
  storage:
    size: 50Gi
    storage_class_name: <gp3 | premium-rwo | managed-csi-premium>

auth:
  mode: <local | oidc>
  initial_admin_email: <admin@your-domain>
  # If oidc: also set issuer, client_id, client_secret env ref.

llm:
  provider: <bedrock | vertex | anthropic | azure_openai>
  # Provider-specific fields per the per-cloud guide.

resources:
  api:        { replicas: 2, cpu: "1",  memory: 2Gi }
  lakehouse:  { replicas: 1, cpu: "4",  memory: 16Gi }
  frontend:   { replicas: 2, cpu: 500m, memory: 512Mi }
  job_runner: { replicas: 1, cpu: 500m, memory: 1Gi }
Then show the filled-in config.yaml to the human and ask them to confirm before you proceed. Diff it against their answers. Flag anything you had to guess. Export the secrets the file references:
export POSTGRES_PASSWORD="..."
# Object-store credentials (S3 access key, GCS HMAC pair, or Azure storage key)
# OIDC_CLIENT_SECRET if auth.mode: oidc
Pull these values from Phase 2’s outputs. Never echo secrets back into the chat transcript; reference them by env var name only.
Do not commit config.yaml to a public repo while the secret env vars are exported in your shell. For prod installs, recommend sourcing secrets from a secret manager (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, 1Password).

Phase 4: Install Definite

The CLI install is identical across clouds. Run, in order:
# 1. Install the CLI
curl -fsSL https://storage.googleapis.com/definite-public/definite-onprem/install.sh | sh
definite version

# 2. Bootstrap cluster-level prereqs (ingress, cert-manager, agent-sandbox CRDs)
definite bootstrap --acme-email <human's email>

# 3. Discover the load balancer address (and finalize HOSTNAME if it was deferred)
kubectl get svc ingress-nginx-controller -n ingress-nginx \
  -o jsonpath='{.status.loadBalancer.ingress[0].ip}{.status.loadBalancer.ingress[0].hostname}'

# 4. Preflight
definite doctor --config config.yaml

# 5. Deploy
definite init --config config.yaml
If HOSTNAME was deferred in Q3 (demo nip.io flow), build it now from the LB IP and update config.yaml before running definite doctor. If definite doctor fails, fix the failure before running definite init. Do not pass --skip-preflight. The most common failures and fixes are in the Troubleshooting section of each per-cloud guide.

Bootstrap the initial admin

definite init does not auto-create an admin. After the pods are Ready:
ADMIN_PASSWORD=$(openssl rand -base64 24 | tr -dc 'A-Za-z0-9' | head -c 24)
kubectl set env deploy/definite-api -n <NAME_PREFIX> \
  INITIAL_ADMIN_EMAIL=<human's email> \
  INITIAL_ADMIN_PASSWORD="$ADMIN_PASSWORD"
kubectl rollout status deploy/definite-api -n <NAME_PREFIX>
Print the admin password back to the human and tell them to save it in a password manager. It is not recoverable.

Phase 5: Verify

  1. definite status --config config.yaml — all pods Running, ingress has an address.
  2. Open https://<HOSTNAME> in a browser. Wait for cert-manager to issue the cert; this can take 60-120 seconds on the first request.
  3. Log in with the admin email + password from Phase 4.
  4. Create a test connection: in the UI, Connect a databasePostgreSQL → point at the same Postgres instance the app uses, as a smoke test.
  5. Ask Fi a question against that connection.
If any of these fail, capture logs (definite logs api --tail 200) before debugging.

Hand-off to the human

When Phase 5 is green, summarize for the human:
  • The URL they sign in at
  • The admin email + a reminder where the password is saved
  • The path to config.yaml (they’ll need it for definite upgrade)
  • The per-cloud guide’s Day-2 section (/on-prem/<cloud>#day-2-operations)
  • Next steps: Connect a data source, set up the MCP server, add SSO if they started with local auth

When to escalate

Stop and tell the human to email hello@definite.app if:
  • The cloud account is missing a permission you can’t grant yourself, and the human can’t grant it either.
  • The LLM provider rejects model access and the human’s admin doesn’t respond within an hour.
  • definite doctor fails three times for distinct reasons.
  • definite init succeeds but pods crash-loop with errors that aren’t in the per-cloud Troubleshooting table.
  • The human asks for anything beyond install (capacity planning, custom registry mirrors, air-gapped install, FIPS compliance, custom sandbox network policies).
Open issues in definite-app/definite-onprem for reproducible bugs.