yeke.io · docs
Installation
YEKE runs as a single container. Community installs with one command; on first start you confirm the address and certificate in the browser. Everything else is in the UI.
Requirements
You connect a Kubernetes cluster after installation.
- A machine with Docker.
- Access to Docker Hub — the
nairotech/yekeimage is public and multi-arch (amd64 + arm64). If your network has no outbound access, see Air-gap installation. - An address your clusters can reach — this machine's DNS name or IP. Agents connect to YEKE through it.
- For Enterprise, a signed license block (pasted during setup; having it as a file is enough) and
openssl(below).
The UI, the API and the agent tunnel come from the same container, on the same port; you don't need a separate reverse proxy in front of it.
One command
This command is the whole Community (SQLite) install.
docker run -d --name yeke --restart unless-stopped -p 443:8443 \ -v yeke-data:/var/lib/yeke \ nairotech/yeke:0.84.3
Don't lose the encryption key: core writes it to the volume as
snapshot.key on first start; without it, encrypted records won't open. To keep
it yourself, pass -e YEKE_SNAPSHOT_KEY before the first start.
If you'd rather mount your own directory
It has to belong to the user core runs as (65532); with a
root-owned directory core doesn't start and logs the command that fixes it:
sudo install -d -m 700 -o 65532 -g 65532 /opt/yeke/data docker run -d --name yeke --restart unless-stopped -p 443:8443 \ -v /opt/yeke/data:/var/lib/yeke \ nairotech/yeke:0.84.3
On this route only the -v line changes in the commands elsewhere on this page.
Backup: the yeke-data volume
Everything the installation holds lives in this volume, in two files:
core.db (cluster inventory, users, operation history, audit trail, system
settings) and snapshot.key — the 32-byte encryption key core generates on first
start. Direct-mode kubeconfigs, your AI provider keys, your hook secrets, rollback snapshots,
and the private keys of an uploaded certificate and of YEKE's own CA sit in the database
encrypted with that key.
Back the two up together. A database backup without the key opens, but cannot read a
single encrypted record — and the symptom is quiet: core does not crash,
/healthz still returns 200, it just cannot reach your clusters. Measured on
2026-08-10. Commands: Upgrades and backups.
If you keep the key outside the volume with YEKE_SNAPSHOT_KEY, do it before
the first start (what stays in the deployment); don't move a
running installation to that route later: records encrypted so far won't open with a
different key.
First start
- Read the setup token. Core prints a setup token to the log on first start:
The token can be used once and is valid for 60 minutes; if it expires,
docker logs yeke | grep -i SETUP:
docker restart yekeissues a new one. - Open
https://<server>. Get past the browser's one-time certificate warning: YEKE uses a temporary certificate on first start. - Create the first administrator. Paste the token and pick a username and password; this account is the installation's owner. On a PostgreSQL installation the form also asks for the license block.
- The "Address & certificate" step. The address must be the one your clusters will connect
to — correct it if you came in through
localhost. The certificate is issued by YEKE's own CA by default; to use your organization's certificate, pick "My own certificate". - Download the CA and trust it. Get it with "Download CA certificate" on the last
screen and add it to your operating system's or browser's trusted roots. For the CLI:
yeke login https://<server> --ca-file yeke-ca.crt.
Enterprise (PostgreSQL)
PostgreSQL mode needs the ha-postgres feature in an Enterprise license. YEKE connects to your organization's existing PostgreSQL through YEKE_DB_URL.
Generate the snapshot key first and store it in a password vault. In PostgreSQL mode core does not generate the key, and if the key is lost, encrypted records do not come back.
openssl rand -hex 32
docker run -d --name yeke --restart unless-stopped -p 443:8443 \ -e YEKE_DB_URL='postgres://<user>:<password>@<host>:5432/yeke' \ -e YEKE_SNAPSHOT_KEY='<64 hex>' \ nairotech/yeke:0.84.3
- The license is given on the setup screen. On an empty database core starts without a license and creates the schema; the setup form asks for the license block together with the first administrator. After that the license lives in the database, and renewal is on Administration → System → License.
- Managing the license as a file is optional (GitOps, HA). If you pass
YEKE_LICENSE_PATHand a file mount, the license is read from the file, the setup screen doesn't ask for one and the License screen refuses uploads. The file must be readable by65532; core can't read aroot-owned file with mode600. - YEKE creates the database if it is missing. If the database in
YEKE_DB_URLdoesn't exist and the connecting role may create databases, YEKE creates it and continues the setup; if the URL gives no database name, the name isyeke. An existing database is used as it is. Without that privilege, startup stops and tells you the database name, the role and what needs to be done. - If the password contains characters like
@ : / ? #, write them percent-encoded inYEKE_DB_URL. - A key passed with
-eshows up indocker inspect. If you don't want that, pass it from a read-only mounted file withYEKE_SNAPSHOT_KEY_FILE. - The backup is PostgreSQL's backup plus the snapshot key; neither is useful without the other. YEKE does not back up PostgreSQL.
First start is the same as Community: the five steps above. Connection shape, pooling and the license gate are in PostgreSQL; multiple replicas in High availability; moving an existing SQLite installation in Database migration.
Certificate
YEKE serves HTTPS itself. By default it issues and renews the certificate with its own CA; no separate reverse proxy needed.
- Automatic (default) — YEKE renews the server certificate on its own; as long as the CA doesn't change, there is nothing to do in browsers or on agents.
- Your own certificate — System settings → Address & certificate → "Use my own certificate": the certificate chain, an unencrypted private key, and the root CA if it's an internal one. It applies on save, without dropping open connections; the private key is never shown again. To renew, upload the new one in the same place. For agents, Shell and the CLI to trust a certificate signed by your internal CA, see Internal CA.
- If a proxy or load balancer terminates TLS in front of YEKE — System settings →
Address & certificate → More → "Serve plain HTTP to the network". After a restart YEKE
serves plain HTTP on
8080, doesn't open8443and doesn't use its own CA; change the publish to-p 8080:8080. If the proxy is on the same machine,-e YEKE_HOST=0.0.0.0 -p 127.0.0.1:8080:8080in the deployment gives the same result.
To supply the certificate as files, use YEKE_TLS_CERT_FILE and
YEKE_TLS_KEY_FILE: the certificate section shows as locked in the UI, and when you
replace the files YEKE switches to the new ones within 60 seconds. Mount the directory
read-only, not individual files — a single-file mount keeps the old file when it's replaced
with mv — and make the files readable by 65532, or core doesn't
start.
No HTTP/2. No 80→443 redirect; open the address with
https://. No automatic certificates from public CAs (ACME/Let's Encrypt).
System settings
Settings after installation live in the UI: Administration → System → System settings. A saved value applies without recreating the container.
| Section | What's in it |
|---|---|
| Address & certificate | Public URL, certificate, the CA your clients should trust, serving plain HTTP to the network |
| Network & outbound access | Hook, SIEM export, Git and AI provider hosts; allowed origins, trusted proxies |
| Sessions & access | Session lengths, API token lifetime and rate limit, MCP server, Secret values, shell session approval |
| Data retention | Operation records, shell recordings, chat history, AI egress log, Secret versions |
| AI assistant | Turning the AI assistant on or off, daily token budget |
- Only the owner changes them. Other administrators see the values but can't change them; users who aren't administrators don't see the screen.
- While the hook and SIEM export host lists are empty, the internal network is closed to them. If you'll connect to an ITSM or SIEM on your internal network, fill these in first.
- Changing the public URL affects agents. Before saving, the screen lists the clusters connected through an agent; each needs its manifest applied again with the new address, and YEKE's own CA is re-issued too.
- "Serve plain HTTP to the network" needs a restart; every other field applies on save.
A setting given as an environment variable is locked
These settings can still be given as environment variables (e.g.
-e YEKE_PUBLIC_URL=…). When one is, the field shows as locked in the UI —
"Managed by deployment" — and not even the owner can change it. Remove the line and
recreate the container, and the field goes back to the saved value or the default; the
environment value is never copied into the database.
What stays in the deployment
A few variables have no counterpart in the UI because they're needed before, or independently of, the database. None is required for Community.
| Variable | When |
|---|---|
YEKE_DB_URL | PostgreSQL mode (Enterprise). |
YEKE_SNAPSHOT_KEYYEKE_SNAPSHOT_KEY_FILE | Encryption key. Required with PostgreSQL; with SQLite, if unset, core generates it and writes it to the volume. |
YEKE_LICENSE_PATH | Optional; path of the license file, for GitOps and HA. If unset, the license is given on the setup screen and later on Administration → System → License; with no license the installation runs as Community. |
YEKE_TLS_CERT_FILEYEKE_TLS_KEY_FILE | Certificate from files (Certificate); locks the certificate section in the UI. |
YEKE_PUBLIC_CA_FILE | The root CA handed to clients, from a file (Internal CA); locks the CA field in the UI. |
YEKE_HOST | Puts YEKE in plain-HTTP-only mode when a layer in front of it terminates TLS. |
YEKE_AGENT_IMAGEYEKE_TOOLBOX_IMAGE | Agent and toolbox images from an internal registry (Air-gap installation). |
YEKE_POLICY_MODEYEKE_POLICY_DIRYEKE_POLICY_PACKAGE_PUBLIC_KEYS | Policy source (Policies, Governance). |
YEKE_BOOTSTRAP_TOKEN | You set the first administrator's setup token yourself; spares a scripted install from reading the log. |
What comes next
YEKE is running, but it cannot see a single cluster yet.
- Connect a cluster — agent mode or direct kubeconfig.
- Set up permissions — which Kubernetes identity each person writes under.
Upgrades and backups
An upgrade recreates the container with the same volume; data, key and system settings stay where they are.
docker pull nairotech/yeke:<new-version> docker rm -f yeke # then the same run command, with only the tag changed
- An upgrade is an outage, every single one. The new core can't start until the old one has stopped; the measured window in production is about 60 seconds. The UI ships inside core's image, so even a release that changes one line of UI text is subject to it.
- Migrations run at startup and core prints a
schema vNline to its log; confirm success from that line, not by guessing. - An older YEKE installed without TLS keeps serving plain HTTP on
8080when it moves to the new image with the same volume:8443isn't opened, and nothing specific to new installations is applied to it. - Backup — for Community, the contents of the volume, plus the key if you keep it
outside. Take the backup with core stopped: SQLite's
-walfile is written while it runs, and a half-copied backup is quietly incomplete. For Enterprise, PostgreSQL's backup and the snapshot key.
docker stop yeke docker run --rm -v yeke-data:/v -v "$PWD":/yedek alpine:3.20 tar czf /yedek/yeke-data.tgz -C /v . docker start yeke
The archive carries the file ownership (65532) with it; restoring is just the
same command in reverse, and core boots straight off the restored volume. The target has to
be an empty volume — on a new machine, Docker creates it fresh when you run this command. If
you mounted your own directory instead, skip both of these: copying the directory is
enough.
docker run --rm -v yeke-data:/v -v "$PWD":/yedek alpine:3.20 tar xzf /yedek/yeke-data.tgz -C /v
Locked out by a setting
If you saved a wrong value in System settings and can no longer reach the UI, the recovery tool in the image fixes the setting in the database. Core does not need to be stopped.
docker exec yeke node tools/yeke-reset-settings.mjs --list docker exec yeke node tools/yeke-reset-settings.mjs <key> docker exec yeke node tools/yeke-reset-settings.mjs <key>=<json-value> docker exec yeke node tools/yeke-reset-settings.mjs --all
Key names are in the --list output. A running core picks up the change on its
own; only "Serve plain HTTP to the network" needs a restart. The most common case is turning
that field off while only 8080 is published — the way back:
docker exec yeke node tools/yeke-reset-settings.mjs address.plainHttpExternal=true docker restart yeke
If the container isn't running, run the tool once against the same volume (for a PostgreSQL
install, also pass --network yeke and -e YEKE_DB_URL=…):
docker run --rm -v yeke-data:/var/lib/yeke --entrypoint node \ nairotech/yeke:0.84.3 tools/yeke-reset-settings.mjs --list
--all leaves YEKE's own CA alone. If you change a setting that's
locked by the deployment, the environment variable stays in force. The operation is written to
the audit log.
If you forgot your password
There is no in-UI recovery when the one administrator forgets their password, or their account gets locked, and nobody else can sign in. Anyone with exec access to the container can issue a new password setup token from the command line.
An operator with container access runs whichever of these two matches their setup. Core does not need to be stopped.
docker exec yeke node tools/yeke-reset-password.mjs admin
kubectl -n yeke-system exec deploy/yeke-core -- node tools/yeke-reset-password.mjs admin
The tool does not pick a password: it prints a one-time password setup token, valid for
60 minutes, to the terminal. The user pastes that token into /set-password
and chooses their own password. Generating a new token invalidates the previous one.
If the authenticator app is gone too, add --reset-mfa; it clears the MFA
enrolment and recovery codes along with the token, and the user can set MFA up again after
signing in.
This only works for local, active accounts. An LDAP/OIDC account's password is reset in the directory, not with this tool; a disabled account has to be re-enabled by an administrator first. The operation is written to the audit log.
Anyone who can run this already has exec access to the container's data directory and database — this does not open a new privilege. No password ever reaches the terminal; only the token does. The API rule is unchanged: the setup owner's password still cannot be reset by another user from the UI.
Kubernetes
Running core inside a cluster is supported too; multiple replicas (high availability) are only available this way.
A manifest set is ready: namespace, ReadWriteOnce PVC, a single Deployment
(strategy: Recreate), Service and a standard Ingress. TLS terminates at the Ingress;
YEKE listens on plain HTTP and doesn't generate its own CA. The public URL isn't in the
manifest: the "Address & certificate" step on first start fills it with the Ingress address.
We do recommend putting the key in a Secret — a backup that snapshots the PVC would
otherwise carry the key with it and make the encryption pointless. The set has a few fields
you'll need to adapt (hostname, StorageClass, Ingress class);
ask and we'll send
them.
You don't have to install inside the cluster it manages, and usually you don't want to: when the cluster YEKE manages goes down, the UI that would fix it needs to still be up.
Stuck on a step? Write to us.
If a step doesn't go as expected, reach out directly.