7. The Runner
A Runner runs a folder's scheduled flows around the clock, on a machine the folder owner controls (a small server, a NAS, a Raspberry Pi), even when nobody has LeavenIT open.
7.1 How it works
- The Runner is a small program, delivered as a Docker image:
ghcr.io/alexandrecrbpro-stack/leavenit-runner:1. - It belongs to one data area (a shared folder, My Workshop, or a folder with separate data) and only acts there.
- It needs that data area to use your own storage (chapter 6). It holds no storage key: LeavenIT signs each read and write, like for a browser.
- It only makes outbound connections: every 5 seconds it asks LeavenIT whether a scheduled flow is due. No port to open, no domain name, no certificate.
- It runs the same SQL engine as the browser (SQLite 3.49 with the same functions), so a block gives the same result in both. Each block runs in its own process, stopped at its time limit.
- It acts on behalf of the folder owner, within that folder, with the same rules as the website.
- Limits per block on a Runner: 30 minutes, about 3 GB of memory for the engine. Very large tables (tens of millions of rows) are not supported yet.
7.2 What you need
- A machine that stays on, with Docker, 64-bit (x86-64 or ARM64), 1 GB of memory or more.
- The data area already on your own storage (chapter 6).
- To be the owner of the folder.
7.3 Adding a Runner in LeavenIT
- Workshop → the folder → ⋯ next to its name → Runners. (For a folder with separate data: its ⋯ → Runners.)
- Add a Runner → name it after the machine ("Hetzner", "Home NAS") → Get the command.
- LeavenIT shows a pairing code (
LVN-XXXXX-XXXXX, single use, valid 30 minutes) and the full command, on one line:
docker run -d --name leavenit-runner --restart unless-stopped --read-only --tmpfs /tmp -v leavenit-runner:/data -e LEAVENIT_URL=<LeavenIT address> -e LEAVENIT_ANON_KEY=<LeavenIT public key> -e LEAVENIT_PAIRING_CODE=LVN-XXXXX-XXXXX ghcr.io/alexandrecrbpro-stack/leavenit-runner:1
The address and the public key are LeavenIT's public values, already filled in. The pairing code is personal: don't share it.
4. Copy the command, run it on the machine (7.4). The panel shows "✓
If the code expired, the panel offers New code.
7.4 Machine guides
A small cloud server: Hetzner Cloud (tested end to end)
- An SSH key on your computer (PowerShell on Windows, Terminal on Mac/Linux):
Press Enter at each question. Show the public key:ssh-keygen -t ed25519 -C "leavenit-runner"Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub(Windows) orcat ~/.ssh/id_ed25519.pub(Mac/Linux). Never share the file without.pub. - console.hetzner.cloud → New project → Add Server:
- Location: Falkenstein or Nuremberg.
- Image: Ubuntu 24.04.
- Type: Shared vCPU, the smallest (CAX11 ARM64, or CX22 x86).
- SSH keys: Add SSH key, paste the
ssh-ed25519 …line. - Firewalls: Create Firewall keeping only inbound SSH (port 22).
- Create & Buy now. Note the IPv4 address.
- Connect:
ssh root@<IPv4 address>(answeryesthe first time). - Install Docker:
curl -fsSL https://get.docker.com | sh - Paste the command from LeavenIT (7.3).
- Check:
docker logs leavenit-runner
Scaleway (Instances) and OVHcloud (VPS or Public Cloud) work the same way: Ubuntu 24.04, your SSH key, SSH only in the firewall, then steps 3 to 6.
A Synology NAS
- Package Center → install Container Manager (only on models that support it).
- Control Panel → Terminal & SNMP → enable SSH.
- From a computer:
ssh <your user>@<NAS address>. - Paste the LeavenIT command with
sudoin front, then enter your password. - Check:
sudo docker logs leavenit-runner.
A Raspberry Pi
A Raspberry Pi 4 or 5 with a 64-bit system (Raspberry Pi OS 64-bit). Install Docker with curl -fsSL https://get.docker.com | sh, then paste the command with sudo in front.
A computer with Docker Desktop (for a test)
Install Docker Desktop, start it, paste the command in a terminal (PowerShell on Windows). The Runner stops when the computer sleeps or shuts down: fine for a test, not for real use.
7.5 What the logs say
docker logs leavenit-runner (or docker logs --tail 50 leavenit-runner):
| Line | Meaning |
|---|---|
LeavenIT Runner 1.0.0: engine self-test OK. |
the engine starts, computes and refuses to leave its sandbox |
Paired as "<name>". |
the pairing code was accepted (first start only) |
Runner "<name>" ready. Checking every 5 s. |
waiting for work |
<flow>: run for <time> then <block>: v<n>, <rows> rows |
a scheduled flow ran; each block published a new version of its table |
<block>: failed (<code>) <message> |
a block failed; the flow run is recorded as failed in LeavenIT with this message |
<flow>: paused (<reason>) |
the schedule is paused (for example the flow changed since it was scheduled): review it in LeavenIT |
Problem: <message> |
a temporary problem (network…); it tries again at the next check |
This Runner was removed in LeavenIT. Stopping. Pair it again with a new code to restart it. |
the Runner was removed in LeavenIT: it stopped and forgot its token |
This Runner is not paired yet: start it once with LEAVENIT_PAIRING_CODE. |
started without a code and without a saved token: get a new command in LeavenIT |
LeavenIT expects Runner protocol <n>; this Runner speaks <m>. Update the image. |
the image is too old: update it (7.6) |
Engine self-test failed: … |
the machine can't run the engine: check it's 64-bit with enough memory |
7.6 Updating, stopping, removing
- Automatic updates (recommended): also run Watchtower, which updates the Runner every night at 4:00:
docker run -d --name watchtower --restart unless-stopped -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --schedule "0 0 4 * * *" leavenit-runner - Update by hand:
docker pull ghcr.io/alexandrecrbpro-stack/leavenit-runner:1, thendocker rm -f leavenit-runnerand run the same command again without-e LEAVENIT_PAIRING_CODE=…(the token is kept in theleavenit-runnervolume). - Pin a version: replace
:1by an exact version (:1.0.0). Go back to the previous one by changing this tag. - Stop for a while:
docker stop leavenit-runner(docker start leavenit-runnerto resume). After one hour offline with active schedules, the owner gets a notification: "Your Runner "" has been offline for over an hour. Its scheduled flows are waiting." - Remove for good: in LeavenIT, Runners → Remove → confirm. The Runner stops by itself at its next check and its schedules are paused. Then on the machine:
docker rm -f leavenit-runneranddocker volume rm leavenit-runner. Delete the cloud server if you rented one, so billing stops.
7.7 Security
- The pairing code works once, for 30 minutes. The token the Runner receives is stored only on its machine (in the
leavenit-runnervolume); LeavenIT keeps only a fingerprint of it. - The token only gives access to this folder, only to run its scheduled flows, and is revoked by Remove.
- The Runner holds no storage key and no account password.
- Keep the machine updated (
apt update && apt upgrade -yon Ubuntu), keep only SSH open, and protect your SSH key.
7.8 Troubleshooting
| What you see | Cause | Fix |
|---|---|---|
| "A Runner works with your own storage…" in the Runners panel | the folder's tables are in LeavenIT's storage | connect your own storage first (chapter 6), then Open Storage |
| The panel keeps "Waiting for the Runner…" | the command didn't run, or the code expired | check docker logs leavenit-runner; if needed New code and run the new command |
| "This pairing code is not valid. Create a new one in LeavenIT." | code already used, expired, or mistyped | Add a Runner again |
| Windows PowerShell rejects the command | the command was cut over several lines | copy it again from LeavenIT: it is on one line |
docker: command not found |
Docker isn't installed | install it (7.4) |
permission denied … docker.sock |
your user can't use Docker | put sudo in front of the command |
| "This Runner belongs to another folder." when scheduling | a Runner only serves flows of its own folder | add a Runner to this folder |
| A flow fails with "The tables of this folder are no longer in your own storage." | the folder moved back to LeavenIT's storage | move it to your storage again, or schedule the flow on "This computer" |
| The Runner is offline after the server rebooted | Docker didn't start | systemctl enable --now docker; the Runner restarts by itself (--restart unless-stopped) |