One-command POC on a single VM¶
Stand up the full KDBL Context Lake (K-Lake) stack — database, work queue, workers, API, web console, and a CPU content extractor — on one Docker/Podman VM, with a demo tenant created and its PAT printed, in a single command. This is the fastest path to an evaluable system; when you're ready for a real cluster, see the production deployment guide.
Licence required. The stack is fail-closed — it refuses to start without a valid licence. Ask your KDBL representative for a 30-day evaluation licence and set it before running:
Run the single-command evaluation installer included in your evaluation bundle.
It provisions a self-contained single-node Kubernetes environment on the VM,
applies the evaluation configuration, and onboards a demo tenant. When it
finishes it prints the web console URL, the cluster-admin token, and the demo
tenant's PAT, and maps the VM's ports 80/443 onto the cluster so the console is
served at http://<vm-ip>/ with no extra setup.
Sizing¶
The box runs several memory tenants at once — the database, the content extractor, and the Kubernetes control plane.
| Profile | vCPU | RAM | Disk | What it runs |
|---|---|---|---|---|
| Comfortable (recommended) | 8 | 16 GB | 80 GB SSD | The fast engine — keyword search over text and office documents — with working headroom |
| Hard floor (demo/eval, small docs) | 6 | 16 GB | 60 GB SSD | The same, with none to spare |
| Full document coverage | 12 | 16 GB | 80 GB SSD | Adds the document engine: scanned PDFs, images and structured tables |
The installer measures the machine and proposes the largest extraction shape that fits. The lean shape — the fast engine alone — reserves about 4.7 vCPU and 6 GB, so it fits either of the first two profiles. Adding the document engine (three fast-engine pods plus one document-engine pod) reserves about 11 vCPU and 12 GB, which is why full document coverage wants a 12-vCPU box; adding audio/video transcription on top reserves about 16 vCPU and 15 GB.
4 vCPU is not viable, and earlier releases of this page said it was. Even
the lean shape reserves about 4.7 vCPU before anything starts, so on a 4-vCPU
box the scheduler simply never places the last pods and they sit Pending —
which looks like a hang rather than a sizing problem. Six fits the stack at
rest; eight leaves headroom for image pulls, a real demo corpus and the
single-node control plane, which is why eight is the recommendation. An upgrade
needs no extra room on top: at one replica each pod is replaced in place rather
than started alongside its predecessor, so a re-run never peaks above the
figures above.
Do not go below 16 GB RAM. 8 GB looks plausible on paper but gets squeezed the moment the extractor parses a real PDF while the database is ingesting, and the installer warns below 15 GB. CPU, not RAM, is what actually stops a run — every shape above runs out of vCPU before it runs out of the 16 GB — but the RAM floor is what keeps the box from thrashing on a real corpus. Three things bite specifically on a single VM:
- Disk, not RAM, is the usual first failure. The worker and especially the content-extractor images are multi-GB; image churn on a small root disk can trigger eviction of pods. Give it ≥60–80 GB on SSD.
- It must be free where container storage lives, not merely on the disk.
Stock RHEL/LVM images cap
/varat 10 GB and leave the rest of the volume group unallocated, so a "100 GB" VM still fails partway through the image pulls withno space left on device. Checkdf -h /varbefore you start, and extend the logical volume if it is short. - The database's shared memory. The default container shared-memory size is too small for eval and can surface as crawl stalls rather than an obvious OOM. The evaluation configuration sizes it appropriately; raise it further if you see stalls under a heavier corpus.
On a Podman host, run the installer with
sudo. The single-node Kubernetes environment needs the system-level container socket and cannot set the host parameters it requires from inside a rootless user namespace. It installs a kubeconfig you own, so your ordinarykubectlworks afterwards withoutsudo. Docker hosts need nosudo.
This is eval-scale guidance. Large-corpus ingest (10M+ rows) is a different, much larger sizing conversation, and a GPU extractor changes the picture entirely.
How the evaluation configuration differs from production¶
The evaluation configuration is a self-contained single-node install, separate from the production Helm deployment — it re-skins the same product for one small node and shares no state with a production cluster:
- Tight scaling bounds — every pool starts at one replica, and the crawl, metadata and extraction pools are capped at two rather than at the ceilings a production size sets. The autoscalers are the same ones production runs, just given very little room.
- Database sized for eval rather than production throughput.
- Worker at reduced concurrency on the direct write path (the high-throughput path is overkill at eval scale).
- Extractor at single-file concurrency with a per-file size ceiling to bound memory.
- Survives reboots. The stack is configured to restart automatically, so closing a laptop lid or rebooting the cloud VM brings K-Lake back up on its own — no need to re-run the installer.
- MCP enabled by default. The MCP server is on out of the box and reachable through the console's ingress, so you can connect an AI client immediately. (Production leaves MCP opt-in.)
Options¶
The installer accepts a few flags:
- Choose the extraction shape — text and office documents only, or adding PDF, OCR and tables, or adding audio and video transcription. This is the flag that decides what your host must be able to fit (see the sizing table above); the installer picks the largest shape the machine can hold.
- Bring up infrastructure only and skip tenant onboarding.
- Name the demo tenant (defaults to
demo). - Skip the content extractor.
- Tear the whole environment down (
--down). - On a host with an NVIDIA GPU, run entity enrichment on the card (
--gpu).
See --help on the installer for the exact flag names.
Tearing down¶
--down deletes the cluster and everything indexed in it — sources,
extracted text, entities and classifications go with it, and a corpus torn down
has to be crawled again from the beginning. So it now says what it costs and
asks before destroying an indexed estate. To keep the data, tear down with
--down --preserve <dir> instead: the database is dumped to that directory
first (with the master key and admin token beside it, readable only by you),
and --restore <dir> puts it back on a fresh cluster later — nothing is
re-crawled or re-enriched. --preserve skips the question; -y answers it for
an unattended run. Without a terminal and without -y, --down refuses rather
than assume consent.
Enrichment on an NVIDIA GPU¶
On an evaluation host with an NVIDIA GPU, entity enrichment runs on the card —
several times faster than on CPU. The installer detects a usable card and asks
before using it (--gpu on insists on it, --gpu off never touches it). The
host needs the NVIDIA driver and the NVIDIA Container Toolkit registered with
Docker; the installer checks both before it builds anything. Moving an existing
evaluation onto a GPU is --down --preserve <dir> followed by
--restore <dir> --gpu on.
Private images¶
During the evaluation period the K-Lake container images may be private. If so, the installer accepts registry credentials (server, username, read token) and creates an image pull secret for you. Once the images are made public for open evaluation, no token is needed and they are pulled anonymously.
After it's up¶
The installer prints a web console URL, a cluster-admin token, and the demo
tenant's PAT. Point the kdbl-control CLI at the instance to verify health and
onboard your first source:
export KDBL_URL=http://<vm-ip>
export KDBL_TOKEN=<ADMIN_TOKEN> # cluster-admin token printed by the installer
# Health check
kdbl-control --api-url "$KDBL_URL" --api-token "$KDBL_TOKEN" doctor
# First source + crawl, as the demo tenant (use the demo PAT it printed)
kdbl-control --api-url "$KDBL_URL" --api-token "<DEMO_PAT>" init
Then open http://<vm-ip>/ and follow the quick start to get a
grounded, verifiable answer.
Upgrading¶
Re-run the installer from a newer kit, or name the release:
The upgrade happens in place. Your data, tenants, sources and credentials are
kept, and helm rollback kdbl -n kdbl returns to the previous release.
Your install options carry over (0.1.46 kits and later). If the evaluation
runs enrichment, hybrid search or plain-English search
reading (--interpret-queries), an upgrade keeps
them without the flags being repeated. It says so as it runs, for example
keeping enrichment from the running install. To remove one, say so:
--no-enrich, --extractor cpu or --no-interpret-queries. Other options,
such as --gpu on, an extraction shape or a --set value, are not carried
over: repeat them on every run.
Kits before 0.1.46 do not carry options over
An older kit's installer builds the release from the flags of the run in
front of it. An upgrade without the original flags therefore removes
enrichment and hybrid search. With such a kit, repeat every flag you
installed with, or better, upgrade with the newer kit. Not sure what you
installed with? helm get values kdbl -n kdbl shows it.
Before upgrading, check the notes for the target version in Upgrading, and schedule the upgrade outside any backup you run against the evaluation.
Serving the console over HTTPS¶
Plain http://<vm-ip-or-hostname>/ works for an evaluation, including single
sign-on. The login page notes that the console is on plain HTTP, because
tokens then cross the network unencrypted. Beyond a private evaluation network,
serve it over HTTPS. The proof of concept is ready for it: install a
certificate from your own CA under Settings › Security › HTTPS certificate
(or press ⌘K / Ctrl+K and type https),
with no installer flags and no kubectl. Upgrades keep it. See
Console HTTPS certificate, then update your sign-in
redirect URIs as it describes. The MCP address your AI assistants use doesn't
change.
Getting help¶
If anything goes wrong, one command collects everything support needs into a single file:
It takes no arguments, asks no questions and changes nothing. The file holds what K-Lake knows about itself, the pod logs (including a crashed container's) and events, and the host's disk and memory history; logs collected on the host are redacted by K-Lake itself before they are packed. Read it, then send it. See Diagnostic packs for what it contains and its options.
Troubleshooting¶
| Symptom | Fix |
|---|---|
Pods Pending on Insufficient cpu/memory |
VM too small — see sizing above. |
Pods ImagePullBackOff |
Private images need a pull token — supply registry credentials (see "Private images"); check the package exists for this version. The installer shows the underlying error and the matching fix. |
Every pod ImagePullBackOff after a host reboot, including ones that ran before |
The cluster cannot resolve the image registry, although the host can (seen with a VPN client alongside the host's DNS resolver). Restart the cluster, which keeps your data: k3d cluster stop kdbl-poc && k3d cluster start kdbl-poc. If it recurs after every reboot, give Docker a DNS server it can always reach ("dns": ["<your DNS server>"] in /etc/docker/daemon.json, then restart Docker). Don't roll back or tear down for this: neither fixes the network, and --down deletes the indexed data. |
| An upgrade removed enrichment or hybrid search | The kit predates 0.1.46 and the upgrade ran without the original flags. Re-run with them (--enrich, --extractor hybrid, --gpu on); the data is intact. See Upgrading. |
| Crawl stalls | The database's shared-memory size is too small — raise it (see sizing). |
| Extractor pod slow to start | The content-extractor image is multi-GB; the first pull can take minutes. Startup doesn't block on it. |
| Re-running the installer | Safe. The environment is reused and onboarding reuses the tenant. |
| Anything you need support for | ./scripts/poc-up.sh support (with sudo on Podman) writes one file to send. See Getting help. |