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, executing deployed workflow apps. Hosts keep running if the Nucleus is unreachable; they dial home for secrets at run start and for management actions.

Enrolling a host

Install a host (three artifacts: single exe, Docker image, live ISO), then connect it: Hosts → Enroll in the Nucleus issues a join token; the agent takes it via CLI (--join), environment (NINER_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 and a mode:

  • Source mode — the compiler emits the app as Bun source; the host runs it with its bundled Bun. Fast installs, ideal while iterating.
  • Executable mode — the artifact is a single compiled binary (Bun --compile), built for the host’s platform — including cross-compilation, e.g. a Windows Nucleus building linux-x64 for a Docker host. No runtime dependencies on the target.

Either way the app is self-contained: its own status server, run history, health endpoint, and trigger serving. The host allocates ports, supervises the process, restarts on request, and distinguishes stopped (intentional) from failed (crashed).

x64 note: compiled executables use Bun’s standard build, which requires AVX2. On Proxmox set the VM CPU type to host — a kvm64-class vCPU kills the app at launch (exit 132).

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, version drift and a logs drawer streaming the app’s 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.

  • 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:

    1. A filesystem labelled NINER_DATA → mounted as the data directory. Never reformatted.
    2. Otherwise, the first provably blank disk (no filesystem signatures, no partition table; removable/optical/read-only devices excluded) → formatted exactly once, labelled NINER_DATA.
    3. 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.

Scale expectations

The management plane is light: a host comfortably manages 100 deployed apps (~18 MB RAM per idle app, monitoring round-trips under 50 ms, restarts ~300 ms). Bulk provisioning is bound by compile time — prefer executable artifacts built once and pushed to many hosts.