Skip to content

The runner

The runner is the open-source lokadb runner. It runs in your network, next to your LokaDB proxy, and does all the database work of LokaDB Cloud: it checks your database and your customers', enables LokaDB, moves organizations and moves them back. It holds your database's passwords; LokaDB Cloud never sees them. It only connects out: to the LokaDB API, to your database and control plane, and to your customers' databases through your relay. It listens on no port.

Before you start

  • LokaDB set up as Install on your database says (steps 1 to 8; enable may be left to the panel): the proxy, the relay(s), the control plane, and the proxy's config with control_plane and credentials_key.
  • A host in the network that reaches your database, the control plane and the relays' organization ports, with Docker.

Starting it

  1. In the panel, Setup → Install the runner → Set up the runner. Fill in the form; the panel writes the runner's runner.json and the command that fits it. The command carries a one-time registration token (lrr_…), valid for 30 minutes.
  2. On the runner's machine, save the file as /etc/lokadb/runner.json, put the files it names in place, and set the database's administrator DSN in the shell: export LOKADB_DB='postgres://…'. The DSN stays on this machine.
  3. Run the command:
docker run -d --name lokadb-runner --restart unless-stopped \
  -v lokadb-runner:/state -v /etc/lokadb:/etc/lokadb:ro \
  -e LOKADB_DB -e LOKADB_RUNNER_TOKEN=lrr_… \
  ghcr.io/lokadb/lokadb:vX.Y.Z runner -config /etc/lokadb/runner.json

The image is the open repository's release, ghcr.io/lokadb/lokadb, tagged with the current release (runner in GET /v1/versions). Every file runner.json names, and every file your proxy config names (such as credentials_key), must be at the same path inside the container: keep them under /etc/lokadb, or add a -v PATH:PATH:ro for each (the panel adds them for the files it knows). Add --network host when the database, the control plane or the relay is on the machine's localhost.

A runner.json the panel writes looks like this:

{
  "service": "https://api.lokadb.com",
  "db": "env:LOKADB_DB",
  "spec": "/etc/lokadb/spec.json",
  "owner": "app",
  "proxy_config": "/etc/lokadb/proxy.json",
  "relay": {
    "agent": "relay.example.com:7443",
    "cloud_host": "relay.internal",
    "ca": "/etc/lokadb/relay-ca.crt"
  }
}

On its first start the runner registers with the token (which then stops working), makes its own key and secret, and logs:

registered runner=… account=… key=<fingerprint>

The panel shows the same fingerprint, and so does every customer's installer: that is how your customers' administrators know the passwords they seal go to your runner. Every later start logs runner id=… service=… key=<fingerprint>.

Its config

runner.json. db, control_plane and token may be written as env:NAME (the environment variable, which must not be empty) or file:PATH (the file's content); anything else is taken as written.

Key Default
service The LokaDB API's address. required
name How the panel shows this runner. the host name
state Its state directory (the volume). /state
token The one-time registration token. LOKADB_RUNNER_TOKEN
db An administrator DSN of your database, as for lokadb move-org -db. required
spec The spec file lokadb enable was given. required
owner The role that owns your application's tables. required
proxy_config The proxy's config file: the check reads its fanout policy from it. required
control_plane, credentials_key, credentials_key_old The control plane's DSN and the credentials key files. from proxy_config
relay.agent The relay address(es) the agents connect to, host:port[,host:port]. required
relay.enroll The relay's enrollment address. the first agent host, port 7444
relay.server_name The relay certificate's name, when it differs from the host.
relay.ca The CA certificate (public) the installers get. required
relay.cloud_host The relay as this network reaches the organizations' ports. required
relay.port_min, relay.port_max The organizations' ports on the relay. 15000, 15999
relay.tls require for the organization endpoints' TLS.
relay.sslmode The sslmode to the customers' databases. prefer
relay.status, proxy_status The relays' and proxies' status URLs, passed on in the status reports.
status false: no status reports (the jobs still work). true
lock_timeout, max_pause As for lokadb move-org. 5s, 10s

What it keeps

The volume holds runner.json (a file of its own, not your config): the runner's id and secret, its sealing key, the service's address and the jobs in progress. Keep the volume: without it, the runner needs a new registration, and customers' passwords sealed to the old key cannot be opened (their administrators run the install command again).

Status

Every 30 seconds or so the runner reports its version, its jobs, whether it reaches your database and the control plane, your relays' and proxies' status, and a probe of each organization at a customer. The panel shows it under Agents ("Last status"); the API under GET /v1/accounts/{a}/runners and GET /v1/installations/{i}/status. A runner not heard from for 2 minutes is offline.

Several runners

A second runner on the same database waits for the first: it logs another runner works on this database: waiting (standby) and takes over when the first stops. Use the panel's "Register another runner" for it.

Updating

Compare your runner's version (in the panel, or GET /v1/accounts/{a}/runners) with the current release (GET /v1/versions); a runner that is behind also logs a newer runner is out, once, with the image to pull. To update, pull the newer ghcr.io/lokadb/lokadb image and start the container again with the same volume, config and environment. Jobs that were running when it stopped are reported as interrupted; the move they belong to can be retried.

Removing it

In the panel, Agents → Remove (the account's owner), or DELETE /v1/runners/{r}. Its secret stops working and the runner exits. To register a runner again on the same host, delete the volume (or the runner.json in it) and start it with a new token.

Troubleshooting

It says What to do
no /state/runner.json: give the one-time registration token First start without a token: get the command from the panel.
this registration token is not valid: it was used or it expired Make a new command in the panel (each works once, for 30 minutes).
runner config: … required A required key is missing from runner.json.
control_plane and credentials_key (or the proxy config's) Give them, or a proxy_config that has them.
the service refused this runner's secret: it was removed or registered again Delete the volume's runner.json and register with a new token.
the service no longer speaks this runner's protocol: update the runner Update the image.
does not know jobs of kind …: update it Update the image.
another runner works on this database: waiting (standby) Expected for a second runner.
A move fails with no free relay port Widen relay.port_min…relay.port_max.
A move fails as unreachable, with a hint about pg_hba.conf The customer's Postgres must let lokadb_app_orgN and lokadb_dml_orgN in from the agent's address.
A move fails with the passwords were sealed to another runner key The runner's key changed (a new volume): the customer runs the install command again (a new one: token).

Passwords never appear in its log or its messages.