# Install packages and the Claude skill > The Windows and Linux install packages, the Docker image, and the skill file that teaches an AI assistant in another project how to use KDB. - Category: Getting started - Keywords: install, installer, package, zip, tar.gz, install.sh, install.ps1, PATH, systemd, service, Docker, image, container, docker stop, docker rm, stop-timeout, restart unless-stopped, HEALTHCHECK, healthy, connection refused, retry, 503, Retry-After, KDB\_DRAIN\_TIMEOUT, last shutdown, not clean, uninstall, Claude, AI, skill, kdb skill, kdb skill install, --dir, --url, --home, KDB\_URL, token file, 0600, /skill.md, agent, assistant, KDB\_TOKEN, KDB\_MEMORY, KDB\_MEMORY\_LIMIT, KDB\_READER\_YIELD, KDB\_SNAPSHOT\_READS, KDB\_CORE\_DUMPS, KDB\_CORE\_KEEP, core dump, crash, gdb, kdb.debug, KDB\_DATA\_DIR, KDB\_CONFIG, KDB\_BACKUP\_SCHEDULE, KDB\_BACKUP\_COMMAND, GLIBC\_TUNABLES, kdb.conf, volume - See also: [Quick start](quick-start.md), [kdb serve](cli-serve.md), [Web console](web-console.md), [HTTP API overview](http-overview.md), [Keeping kdb serve safe](server-security.md) KDB ships as one program and three folders of plain files next to it: the web console, the help pages and the Claude skill. There is nothing else to install - no runtime, no libraries, no service to configure first. There are three ways to get it onto a machine. | Way | You get | Best for | |---|---|---| | The Windows package | `kdb--windows-x64.zip` | a desktop or a Windows server | | The Linux package | `kdb--linux-x64.tar.gz`, built static so it runs on any distribution | a VPS or a Linux desktop | | The Docker image | a small Alpine image with the program and its folders | a server you would rather not install anything on | An unpacked package looks like this: ```text kdb---x64/ kdb.exe (Windows) or kdb (Linux) the program - nothing else is inside it web/ the web console help/ the help pages (missing when the package was made without them) skill/skill.md the Claude skill install.ps1 or install.sh, kdb.conf.example, README.md ``` ## Windows Unpack the zip and run the installer from the folder it made: ```powershell powershell -ExecutionPolicy Bypass -File .\install.ps1 ``` It copies `kdb.exe` and its `web`, `help` and `skill` folders into `%LOCALAPPDATA%\Programs\kdb`, adds that folder to **your** PATH (no administrator rights needed) and writes the [Claude skill](install-packages.md#skill). Add `-Token my-secret` to save your token beside the skill, in a file only you can read. | Option | Meaning | Default | |---|---|---| | `-Prefix ` | where the program goes | `%LOCALAPPDATA%\Programs\kdb` | | `-Token ` | the token, saved in the file `token` beside the skill | `$env:KDB_TOKEN` | | `-Data ` | the data folder it suggests | `%LOCALAPPDATA%\kdb\data` | | `-NoPath` | do not touch PATH | - | | `-NoSkill` | do not write the skill | - | Uninstalling is deleting that folder and taking it off your PATH. Nothing is registered with Windows. ## Linux Unpack the tar.gz and run the installer from the folder it made: ```bash ./install.sh # just you: ~/.local/bin, folders in ~/.local/share/kdb sudo ./install.sh --system # everyone: /usr/local/bin, folders in /usr/local/share/kdb sudo ./install.sh --system --service --token my-secret # ...and start it at boot ``` | Option | Meaning | Default | |---|---|---| | `--system` | install into `/usr/local` instead of `~/.local` | - | | `--prefix ` | install somewhere else | `~/.local` | | `--service` | write a systemd unit and start it (needs root and `--token`) | - | | `--token ` | the token for the service and the skill | `$KDB_TOKEN` | | `--data ` | the data folder | `/var/lib/kdb` or `~/.local/share/kdb` | With `--service` the server runs as its own `kdb` user, is restarted if it stops, and can write to its data folder and nowhere else. The unit file holds the token, so it is readable only by root. ```bash systemctl status kdb journalctl -u kdb -f ``` ## Where kdb finds the console, the help and the skill The web console, the help pages and the Claude skill are files, so a new console or help needs the files copied, not a new program. `kdb` looks for each folder in this order and uses the first one that has its files in it (`index.html`, or `skill.md`): | Order | Web console | Help pages | Claude skill | |---|---|---|---| | 1. `kdb.conf` | `"web_dir"` | `"help_dir"` | `"skill_dir"` | | 2. environment | `KDB_WEB_DIR` | `KDB_HELP_DIR` | `KDB_SKILL_DIR` | | 3. next to the program | `web/` | `help/` | `skill/` | | 4. `share/kdb` beside the program folder | `../share/kdb/web` | `../share/kdb/help` | `../share/kdb/skill` | | 5. a source checkout (`build/bin/kdb`) | `web/console` | `docs/help/site` | `.claude/skills/kdb` | - The console's **Settings** page shows the folders in use and what chose each one. They are read-only there. - Files are read when they are asked for, so copying a new help build into `help/` shows at the next page load, without a restart. - A folder that is missing does not stop the server. The HTTP API works, `http://127.0.0.1:9900/` says the console is not installed and lists the folders it looked in, and `/help/` says how to build the help. A `kdb.conf` that names all three: ```json { "data_dir": "E:/kdb-data", "web_dir": "E:/kdb/web", "help_dir": "E:/kdb/help", "skill_dir": "E:/kdb/skill" } ``` ## Docker ```bash docker run -d --name kdb -p 9900:9900 -p 8832:8832 \ -e KDB_TOKEN= -v kdb-data:/data kdb ``` The data lives in the named volume `kdb-data`, so removing and recreating the container does not lose it. The server refuses to start without `KDB_TOKEN`: the image listens on all addresses, so a published port can reach it, and KDB does not do that without a secret. The image holds `/usr/local/bin/kdb` and its folders in `/usr/local/share/kdb/web`, `help` and `skill` (named by `KDB_WEB_DIR`, `KDB_HELP_DIR` and `KDB_SKILL_DIR`). The image build only compiles `kdb` and copies those folders from the source tree, so run the help build first when the help pages should be in it. - Add `--restart unless-stopped` so the server comes back by itself after Docker or the computer restarts. - The image has a health check: `docker ps` shows `healthy` once the HTTP port answers `GET /health`. While the server is stopping, `/health` answers 503. - Anything after the image name is added to `kdb serve`, for example `... kdb --threads 4`. The settings of the image, all given with `-e NAME=value`: | Variable | Meaning | Default in the image | |---|---|---| | `KDB_TOKEN` | the secret every request sends as `Authorization: Bearer `. The start script passes it as `--token`; the program itself reads no `KDB_TOKEN`. | none: required | | `KDB_MEMORY` | `--memory`, in MB (passed as the flag) | `256` | | `KDB_MEMORY_LIMIT` | one limit for everything the server holds ([memory limit](cli-serve.md#memory-limit)), like `3GB` | 85% of the container's memory limit, else of Docker's memory | | `KDB_DATA_DIR` | the data folder | `/data` | | `KDB_CONFIG` | the settings file (passed as `--config`) | `/data/kdb.conf` | | `KDB_DRAIN_TIMEOUT` | how long running requests may finish on a stop | `5s` | | `KDB_READER_YIELD` | `on`: reads do not wait for a long trigger or transaction ([--reader-yield](cli-serve.md#kdb-serve)). `off`: they wait. | `on` | | `KDB_SNAPSHOT_READS` | `on`: a read of a table being written reads a snapshot of the committed rows and does not wait ([--snapshot-reads](cli-serve.md#kdb-serve)) | `off` | | `KDB_PER_TABLE_READS` | `off`: every read waits for every writer, as before ([--per-table-reads](cli-serve.md#kdb-serve)) | `on` | | `KDB_READ_ONLY_CALLS` | `off`: every `CALL` is a transaction, also one that only reads ([--read-only-calls](cli-serve.md#kdb-serve)) | `on` | | `KDB_CORE_DUMPS` | `on`: a crash leaves a core dump in `/data/_logs/cores` (kdb runs from that folder). At the next start the dump is renamed with its time. `off`: no dumps. The unstripped program for reading one is `/usr/local/lib/kdb/kdb.debug` (`gdb kdb.debug core.