yeke.io · docs

Installation

YEKE is a single container. It installs on one machine with one command; the first block below is copy-paste-and-run. A second command below shows every setting; sections on upgrades and Kubernetes follow after that.

Requirements

Three things. A Kubernetes cluster is not one of them — you connect that afterwards.

  • A machine with Docker. Docker Compose is not required; use it if you'd like (further down).
  • openssl — or anything else that can produce 32 random bytes.
  • Access to Docker Hub — the nairotech/yeke image is public and multi-arch (amd64 + arm64).

There's no separate web container and no reverse proxy in front of it anymore. The UI, the API, and the agent tunnel all come from the same process, the same port — this image is the only thing you install.

One command

Copy it, paste it. No separate config file, no repo to clone.

docker run -d --name yeke --restart unless-stopped -p 8080:8080 \
  -v yeke-data:/var/lib/yeke \
  -e YEKE_SNAPSHOT_KEY="$(openssl rand -hex 32)" \
  nairotech/yeke:0.7.3

Pin the version tag — don't write latest: core's version also determines the tag of the agent image that gets installed in your cluster. If the tag drifts, the agent ends up with a protocol mismatch. Released tags are on Docker Hub.

Wait for it to come up

/healthz doesn't require auth and doesn't touch the database; it's the cheapest signal that things are ready. Takes a few seconds:

until curl -sf http://localhost:8080/healthz; do sleep 1; done

This command prints {"status":"ok"} and exits. The container has no built-in healthcheck, so docker ps never shows (healthy) — that's expected, not a sign something went wrong.

Create the first administrator

On first boot there are no users at all; core generates a setup token and prints it to the log:

docker logs yeke 2>&1 | grep -A1 SETUP

Open http://localhost:8080/, paste the token, and pick a username and password. The token is valid for 60 minutes and can be used once; if it expires, docker restart yeke issues a new one.

Save the key somewhere now

YEKE_SNAPSHOT_KEY encrypts rollback snapshots and direct-mode kubeconfigs. In the command above, the key lives only in the container's configuration — the moment you remove and recreate the container (an upgrade requires exactly that), your only copy is gone.

Losing it fails quietly enough to mislead you: core started with the wrong key does not crash, /healthz still returns 200, and the setup screen doesn't reopen either — the only symptom is that login fails, forever. Measured on 2026-08-10. Read the key out and put it in your password vault:

docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' yeke | grep YEKE_SNAPSHOT_KEY

For anything permanent, keeping the key in a file rather than on the command line is better — the next section does exactly that.

Every setting, out in the open

The permanent version of the same install: key in a file, public address declared, license attached. Delete whichever line you don't need.

First generate the key once and write it to a file. If the file already exists this leaves it alone — re-running this line does not rotate your key:

install -d -m 700 /etc/yeke
[ -f /etc/yeke/snapshot.key ] || openssl rand -hex 32 > /etc/yeke/snapshot.key
chmod 600 /etc/yeke/snapshot.key
docker run -d --name yeke --restart unless-stopped \
  -p 8080:8080 \
  -v yeke-data:/var/lib/yeke \
  -v /etc/yeke/license.txt:/etc/yeke/license.txt:ro \
  -e YEKE_SNAPSHOT_KEY="$(cat /etc/yeke/snapshot.key)" \
  -e YEKE_PUBLIC_URL="https://yeke.ornek.com" \
  -e YEKE_ALLOWED_ORIGINS="https://yeke.ornek.com" \
  -e YEKE_LICENSE_PATH="/etc/yeke/license.txt" \
  nairotech/yeke:0.7.3

The last three lines are optional. If you don't have a license, or you'd rather upload it from the UI, remove the YEKE_LICENSE_PATH line and its mount line together. Removing just one of them creates a quiet mess: Docker, trying to mount a file that doesn't exist, creates an empty directory at that path instead; core can't read a directory, rejects the license, and keeps running as Community — the install looks fine, but it catches up with you later when you try to copy your actual license file to that path.

VariableRequiredWhat it does · what happens if left empty
YEKE_SNAPSHOT_KEYRequired The 32-byte key (64 hex characters or base64) that encrypts snapshots and direct-mode credentials. Without it core doesn't start at all — it explains why and exits.
YEKE_PUBLIC_URLIf you'll add a cluster The absolute address at which core is reached from the outside; the agent install manifest uses this address. Left empty, core boots fine and login works — only adding a cluster in agent mode stops, with PUBLIC_URL_NOT_CONFIGURED. Core does not guess this address: most installs listen on 0.0.0.0:8080, and that address is not reachable from inside the cluster.
YEKE_ALLOWED_ORIGINSNo Extra origins accepted by the CSRF/Origin check (comma-separated). Needed only when you put a reverse proxy (Cloudflare, nginx, Traefik) in front of core and that layer presents an external address different from the Host core sees.
YEKE_LICENSE_PATHNo Path to the Enterprise license file. Left empty, the install runs as Community: a cap of 3 clusters / 5 users, every core capability unlocked, never expires. Set, it becomes that boot's only license source and the license can no longer be uploaded from the UI.
YEKE_BOOTSTRAP_TOKENNo A fixed setup token for the first administrator — saves you from reading the log if you're scripting the install. Left empty, core generates one at random and logs it.

You don't need to define any YEKE_* variable that isn't in this table. Three of them — YEKE_ALLOW_HEADER_IDENTITY, YEKE_DEV_USER, YEKE_DEV_GROUPS — were removed, and if defined core doesn't start at all: authentication exists precisely because those three were shut off, and silently ignoring them would let you believe it "still works the old way."

What comes next

YEKE is running, but it cannot see a single cluster yet.

Upgrades and backups

An upgrade recreates the container. Data and key live on disk, so they don't change — if you kept the key on the command line, read it out first.

docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' yeke | grep YEKE_SNAPSHOT_KEY
docker pull nairotech/yeke:<new-version>
docker rm -f yeke
# then the same run command: new tag, SAME key
  • An upgrade is an outage, every single one. The database is single-writer SQLite: the new core can't start until the old one has stopped. The measured window in production is about 60 seconds. Even a release that changes one line of UI text is subject to this outage — the UI ships inside core's image.
  • Migrations run at startup and core prints a schema vN line to its log; confirm success from that line, not by guessing.
  • Backup — the yeke-data volume plus the /etc/yeke directory. Together they're the entire install; a data backup without the key is useless.

Compose and Kubernetes

The single command is enough for most installs. If you want the service definition to be declarative, there are two more paths; both run the same image.

Docker Compose

No need to clone a repo — this is the whole file:

services:
  core:
    image: nairotech/yeke:0.7.3
    ports:
      - "8080:8080"
    environment:
      YEKE_SNAPSHOT_KEY: ${YEKE_SNAPSHOT_KEY:?key is required}
      YEKE_PUBLIC_URL: ${YEKE_PUBLIC_URL:-}
    volumes:
      - core-data:/var/lib/yeke
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8080/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 10s
      timeout: 3s
      retries: 5
      start_period: 10s
    restart: unless-stopped

volumes:
  core-data:

Put the key in a .env file next to it and run docker compose up -d. The :? mark is deliberate: if the key is missing, up never starts. On this path docker ps does show (healthy) — the healthcheck is part of this file, not the image.

Kubernetes

Running core inside a cluster is supported and a manifest set is ready: namespace, ReadWriteOnce PVC, a single Deployment (strategy: Recreate), Service, and a standard Ingress. The key is not in the manifests — you create the Secret by hand. The set is short but has a few fields you'll need to adapt to your setup (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.

Every command on this page was actually run while it was written. If a step still does not go as expected, reach out directly.