Kumo.io

Docs Self-hosting & operations

Self-hosting & operations

Run Kumo.io as separate services

Describe your installation in a short deployment spec, and kumo deployment renders it into a Docker Compose project, converges it, and keeps it converged on every re-run.

Applies to: Self-hostedPlan: Allplan before you applyresumableDocker Compose

When to use this

Use kumo deployment when one container is not the shape you want — for example to run the API, worker and scheduler as separate containers you can scale independently, or to keep the database in its own container. If one container is enough, run Kumo.io in one container instead; it needs no spec.

You run kumo deployment on the machine that runs Docker, with the Kumo.io CLI and Docker Compose v2 installed. Every container it starts runs the same kumoio/kumo image.

How it works

A deployment spec is a YAML file describing the installation you want: the image, where the database lives, which roles run and how many of each. kumo deployment compares that spec with what is actually running and makes the difference:

  1. kumo deployment validate checks the spec without touching Docker.
  2. kumo deployment plan shows what would change, and changes nothing.
  3. kumo deployment apply converges the running installation to the spec.

The Compose file is generated from the spec every time — never edit it by hand. Apply holds a lock while it runs and records each step, so an interrupted apply resumes where it stopped when you run it again.

Choose a topology

Topology What runs Database
All-in-oneOne appliance container (app, API, admin API, plus a job worker)A PostgreSQL container on a named volume
All-in-one, your databaseOne appliance containerYour PostgreSQL, from a connection string
Split rolestenant-api, admin-api, ui, worker and scheduler containersA PostgreSQL container on a named volume

In the split topology, raise a role's replicas to run more of it. Only one scheduler is active at a time, so one replica is enough.

Only the all-in-one appliance role can connect to your Kumo.io account, and a self-hosted installation stays restricted until it is connected or licensed. A split-role installation can be unlocked only with a license file.

Licenses for self-hosted installations are not available yet, so use an all-in-one topology today.

Write the spec

This spec runs the all-in-one topology on a bundled PostgreSQL container:

apiVersion: deployment.kumo.io/v1alpha1
kind: Deployment
metadata:
  name: appliance
spec:
  policy: production
  target:
    driver: compose
    namespace: kumo
    compose:
      image: kumoio/kumo:<version>
  release:
    version: <version>
    digest: 'sha256:<image-digest>'
  storage:
    backend: postgres
    mode: managed-local
  topology:
    profile: appliance
    roles:
      appliance:
        replicas: 1
  bootstrap:
    systemSeed: release
    templates: release
  upgrade:
    migrations: automatic
    backup: required
    maximumUnavailable: 1
  observability:
    metrics: enabled
    logs: stdout

To use your own database, change storage to:

  storage:
    backend: postgres
    mode: external
    dsnRef: 'env://KUMO_PG_DSN'

For split roles, set topology.profile: split and list the roles:

  topology:
    profile: split
    roles:
      tenant-api:
        replicas: 1
      admin-api:
        replicas: 1
      ui:
        replicas: 1
      worker:
        replicas: 1
      scheduler:
        replicas: 1

You can also scaffold a spec with kumo deployment init --name <name> --profile appliance --out <file> and edit it. A scaffolded spec is fully written out, so a later Kumo.io version can never change your installation by changing a default. The profiles are local-dev, appliance and aws-fargate. There is no Kubernetes driver yet, so init offers no Kubernetes profile and refuses --driver kubernetes.

Pin the image

A spec with policy: production must pin the image digest, and apply checks that the image on the machine matches it. Pull the image, then read its digest:

docker pull kumoio/kumo:<version>
docker image inspect --format '{{index .RepoDigests 0}}' kumoio/kumo:<version>

Put the sha256:… part in release.digest.

The production policy also requires durable storage and upgrade.backup: required. kumo deployment validate tells you exactly which rule a spec breaks.

Put secrets in the sidecar env file

Secrets never go in the spec or the generated Compose file. Every Kumo.io container reads an optional env file named after the spec's namespace — kumo.env for the spec above — next to the generated Compose file. The generated file's header names it; run kumo deployment render --file <spec> --out <dir> to see exactly what apply will run.

Variable When
POSTGRES_PASSWORDBundled database: the password for the PostgreSQL container
KUMO_PG_DSNYour own database: its connection string (required)
KUMO_AUTH_TOTP_KEYThe key that protects two-factor secrets (32 random bytes, base64url). Unset, each container creates its own; set it so every Kumo.io container shares one
KUMO_ADMIN_API_TOKENS + KUMO_ADMIN_ROLESThe admin API credential — set both, or neither

If you set neither admin variable, Kumo.io creates an admin credential on first boot and prints it once in the container log, exactly as the single container does. If you set only KUMO_ADMIN_API_TOKENS, the admin API refuses to start; if you set only KUMO_ADMIN_ROLES, no token can sign in to it.

The credential-store encryption key needs no configuration: Kumo.io creates it in the database on first boot. Set KUMO_PG_SECRETS_KEK in the env file only if you want to hold that key outside the database. Every other setting is on the configuration reference.

Apply it

kumo deployment plan --file kumo.deployment.yaml
kumo deployment apply --file kumo.deployment.yaml --yes

--yes is required for a policy: production spec. Apply checks Docker is running, verifies the image, starts the database and waits for it to be healthy, runs a one-time bootstrap (schema migrations, system data and the built-in view templates), starts the Kumo.io containers, and waits until every one is running. It ends with an Access section listing the addresses.

Kumo.io's ports are published on 127.0.0.1 only:

Port What
9500The app, and sign-in
9501The tenant API
9503The admin API

To serve your team, put a TLS-terminating reverse proxy in front of port 9500 and set KUMO_EXTERNAL_URL in the env file to the public address.

Then connect the installation to your Kumo.io account.

Day two

Command What it does
kumo deployment status --file <spec>Health and convergence at a glance
kumo deployment plan --file <spec> --detailed-exit-codeExits 3 when the running installation has drifted from the spec
kumo deployment doctor --file <spec>Read-only diagnosis of the target, release and roles; exits 3 when something is blocked
kumo deployment config show --file <spec>The fully resolved configuration, with secrets redacted
kumo deployment operation list --file <spec>Past operations; operation watch <id> follows one
kumo deployment lock show --file <spec>Who holds the apply lock

To change anything — scale a role, upgrade the image — edit the spec and run apply again. See Upgrades.

Back up before you upgrade

On Docker Compose, Kumo.io's data lives in named Docker volumes and apply does not snapshot them for you. Take a database backup before every upgrade — see Backups and restore.

Remove an installation

kumo deployment destroy --file <spec> --allow-destroy --yes

This stops and removes the containers but keeps the volumes, so applying the spec again brings the same data back. To delete the volumes too, add --allow-data-loss. Without it, no data is ever deleted.

See your own cloud in Kumo.io. Read-only access. Nothing in your account changes.

Free Trial