Skip to content

Self-hosting

Install & deploy

Run the whole platform on your own infrastructure. You need a Supabase project for the database and auth, and either Docker or Node.

One-command setup#

The setup script scaffolds .env, generates the encryption secrets, applies database migrations and starts the stack.

bash
bash scripts/setup.sh
powershell
powershell -ExecutionPolicy Bypass -File scripts\setup.ps1

Every service is installed and wired — the Office renderer, the JS sandbox, the Developer-workspace Python runtime and its egress proxy, the lakehouse catalog and its object store, the vector store, the feature store and the Spark cluster — and .env points at all of them. There are no profiles and nothing to opt into: a feature that depends on which flag an installer was given is a feature most installs never see. Budget about 5 GB of images and 8 GB of RAM. --dev runs the app on this host with a dev server and starts the same services beside it, reached on loopback.

It cannot create your Supabase project or guess its keys — it writes the .env, tells you which values to fill in, and you re-run it.

In this guide#

Setup and the deployment targets are on this page. The reference and the operating detail have pages of their own.

Manual setup#

  1. 1

    Create a Supabase project

    It provides Postgres, authentication and storage. Note the project URL, publishable key and service-role key.
  2. 2

    Fill in .env

    Copy .env.example and set the required values below.
  3. 3

    Apply migrations

    npx supabase link --project-ref <ref> then npx supabase db push. This creates every table, policy and storage bucket.
  4. 4

    Start it

    docker compose up -d --build, or npm install && npm run dev. Open http://localhost:8080.

Migrations are not optional

Features whose migrations haven't been applied fail quietly rather than loudly — a storage bucket that doesn't exist means uploads silently don't persist, and a missing column means a setting has nowhere to save. After any upgrade, run npx supabase db push before concluding a feature is broken.

The services#

ServiceContainerWhat it adds
Doc-gen rendererdocgenServer-side PowerPoint/Word/Excel via python-pptx, python-docx, openpyxl and LibreOffice — the "Deep" generation mode.
Notebook runtimenotebook-gatewayReal Python kernels for the Developer workspace, with a gateway and a default-deny egress proxy.
JS sandboxjs-sandboxRuns Function nodes and custom components in deployed and scheduled swarms, in a locked-down container instead of next to the app's credentials.
Lakehouse cataloglakehouse-catalogA Postgres of its own holding the lakehouse's table definitions. Without one — this, or your own in LAKEHOUSE_CATALOG_URL — the lakehouse, SQL models and ML stay off.
Object storeminioWhere the lakehouse Parquet files live. Replace it with S3, R2 or GCS by pointing LAKEHOUSE_S3_* at them.
Spark clusterspark-connectA Spark Connect endpoint for the ETL Spark engine and lakehouse queries on Spark. Idle until SPARK_CONNECT_URL names it; the image is about a gigabyte and it downloads its connector jars on first use.
Vector storeqdrantQdrant, for deployments whose knowledge-base index has outgrown the application database. Idle until VECTOR_STORE=qdrant names it, and retrieval stays on pgvector until it does.
Online feature storevalkeyValkey, holding a feature view's latest row per key so a prediction answers in milliseconds instead of reading the lakehouse. Idle until FEATURE_STORE_URL names it; every lookup reads the lakehouse until it does, which is correct and about sixty times slower.
bash
docker compose up -d --build

Or let the setup script start everything: bash scripts/setup.sh (powershell -File scripts\setup.ps1 on Windows).

Every one is optional, and each degrades to something rather than breaking. Without the renderer, documents are generated in the browser and Deep mode is greyed out with the reason. Without the notebook runtime, opening a notebook shows a panel saying a runtime is required — there is no in-browser fallback. Without the sandbox, custom code still runs on the canvas and the Deploy dialog says plainly that it will fail in headless runs. Without the feature store, feature lookups read the lakehouse exactly as they did before it existed. The last four are inert until an environment variable points at them: start the Spark or vector profile without setting SPARK_CONNECT_URL or VECTOR_STORE and the container runs while nothing uses it.

Observability → Monitoring (superadmin) shows which of these are actually up on this deployment, with the address that answered and live CPU, memory and disk. A profile you chose not to start reads “Not running” rather than as a failure.

Deployment targets#

Docker Compose
The default. Every service on one host, started by one command. Good to a substantial team on one host.
Node behind a reverse proxy
Build and run the server directly. Terminate TLS at your proxy.
Autoscaled VMs behind a load balancer
The app tier is stateless, so run as many identical containers as you need. Set DISABLE_INPROCESS_SCHEDULER=1 and drive background work from one external cron.
Kubernetes
Reference manifests ship for the app (deploy/k8s/app/) and the notebook runtime (deploy/k8s/notebooks/), including the egress policy that keeps kernels off the open internet. Three things bite in practice: set resources.limits.cpu, because the worker count follows it; probe liveness on /api/health and readiness on /api/health/ready, which answer different questions; and strip the quotes from .env before kubectl create secret --from-env-file — unlike Docker Compose it keeps them, and every pod then fails readiness with Invalid supabaseUrl.

Kubernetes — the manifests and a walk-through per cloud — has its own page.

Note

Install problems and their fixes are collected in docs/INSTALL.md in the repository, which is kept up to date as issues are found.