Hosts & deployment
Flowdrome splits management from execution:
- The Nucleus is the control plane. Workflow registry, credentials vault, users & roles, the host fleet, deployments, the approvals inbox. It never executes a workflow.
- A host is the data plane: a machine running the host agent, with the same engine the editor uses embedded inside it. Deployed workflows are served by that engine. Hosts keep running if the Nucleus is unreachable; they dial home for secrets at run start and for management actions.
The split is the architecture’s load-bearing wall. The control plane can restart, upgrade, or sit on the other side of a flaky link without taking a single workflow down — and a host can be a 300 MB live-ISO VM that does nothing but run apps. The screen-by-screen tour of both sides (fleet view, host dashboard, approvals inbox, run drawer) is the Hosts guide.
Enrolling a host
Install a host (four artifacts: single exe, Docker image, Proxmox LXC
template, live ISO), then
connect it: Hosts → Enroll in the Nucleus issues a join token; the agent takes it via CLI
(--join), environment (FLOWDROME_JOIN_*) or its GUI Connect to Nucleus screen. Authorized
hosts appear in the fleet view, grouped by environment, with live status, an open-host link,
and per-host deployments. De-authorizing a host stops it from receiving anything.
Deploying a workflow
From a workflow’s Deploy action, pick a host — that’s the whole decision. The Nucleus pushes
the exact flowdrome.workflow.v1 document you tested (no conversion, no compile step), stamped
with its saved version and deploy time, plus a scoped resolve token for
secrets leasing. The host persists the deploy envelope (it
survives restarts) and registers the workflow with its embedded engine — the unified hosted
runtime: one engine and one worker pool per host, shared by every workflow deployed to it.
The host’s serve layer takes over the triggers: HTTP webhooks, schedules (interval and cron), HTML forms, web chat, WebSocket, Telegram (long-poll and webhook), Slack events, and WhatsApp. Runs execute on the embedded engine with the same envelope capture you saw in the editor. Stopping a deployment is intentional and distinct from a crashed one; removing it uninstalls the document.
x64 note: the host’s engine worker is compiled with Bun’s standard build, which requires AVX2. On Proxmox set the VM CPU type to
host— akvm64-class vCPU kills it at launch (exit 132).
Sub-workflows come along
A workflow that runs sub-workflows installs self-contained. On deploy the Nucleus walks the whole dependency tree and:
- Checks everything exists first — every sub-workflow it uses (transitively), plus the variables and credentials it and its subs reference. Anything missing blocks the deploy with the exact list, so a workflow never installs only to fail on its first run.
- Inlines the sub-workflows into the deployed document. Each Execute Workflow node is expanded into the master graph, so the host serves one workflow: every node runs — and is tracked — in a single run history, and the sub-workflows never appear as separate deployments cluttering the fleet.
The Deploy action previews what an install brings along (“…brings along 3 sub-workflows, embedded to run inline”). Secrets are still never baked in — the host dial-homes for their values at run start; the dependency check only confirms they’re defined.
The same self-contained artifact comes from Export → Self-contained (or
GET /api/workflows/{id}/export?bundle=1) — a single file that installs anywhere with nothing else to bring.
Deploy carries a frozen copy
Sub-workflows aren’t the only dependencies that ride along. A deploy walks the workflow for the tables it reads or writes and the interfaces whose pages run it, and freezes a copy of each:
- Tables deploy with their schema pinned at the deploy-time version. The host serves rows against that frozen schema, so a column dropped or retyped in the Nucleus tomorrow can’t break a running app.
- Interface pages that call the workflow deploy with the workflow, at their current content version, and are served from the host.
The deploy manifest lists all of it up front — the same “checks everything exists first” gate that covers sub-workflows now includes tables and interfaces, each with the exact version being pinned:
GET /api/workflows/{id}/dependencies
→ { ok, subWorkflows[], variables[], credentials[],
tables:[{id,name,version,present}], interfaces:[{id,title,slug,version}] }
Editing the live table or interface afterwards mints a new version (its
version history records it), but active deployments keep
serving their pinned copy — they don’t drift out from under you. The change reaches a host only
when you redeploy. Until then the table/interface’s Where used
view flags each lagging deployment stale, so the impact of a schema or content edit is visible
before you commit it — the same version-badge drift you see for the workflow document itself.
Watching the fleet
- Workflows view — each workflow row expands to its deployments across hosts (matched by
workflow id, so renames don’t orphan deployments), with status, a version badge (
v3in teal when the deployment matches the current saved version, orange when it has drifted behind a newer save), and a logs drawer streaming output through the Nucleus. - Hosts view — fleet health at a glance; each host’s own dashboard shows apps, queues, the run ledger and a Resources tab with per-app CPU/memory/disk telemetry.
- Approvals inbox — every pending approval gate across every authorized host, in the Nucleus header, with approve/reject in place.
The host upgrade story
Host state lives in one data directory; the agent is replaceable around it.
-
Bare exe / Docker: replace the binary or image, keep the data directory / volume.
-
Proxmox LXC: run
flowdrome-upgrade <new-template.tar.gz>inside the container (in-place, the template doubles as the upgrade artifact) — or, with/dataon its own mount point, create a new CT from the new template andpct move-volumethe data volume across. -
Live ISO appliance: the OS is the ISO — upgrading is swapping the attached ISO and rebooting. At boot the appliance adopts its data disk by label:
- A filesystem labelled
FLOWDROME_DATA→ mounted as the data directory. Never reformatted. - Otherwise, the first provably blank disk (no filesystem signatures, no partition table;
removable/optical/read-only devices excluded) → formatted exactly once, labelled
FLOWDROME_DATA. - No candidate disk → the host runs ephemeral and says so on the console.
Host identity, apps and run data ride the data disk across ISO swaps. OS-level changes (including passwords) live on the boot overlay and reset every reboot — that is the appliance contract.
- A filesystem labelled
Scale expectations
The management plane is light: a host comfortably manages 100 deployed workflows on its shared runtime (monitoring round-trips under 50 ms, restarts in the hundreds of milliseconds). Deploys are pushes of a JSON document — provisioning many hosts is bound by your network, not by a build step.