Rename Installation to Instance

Follows the portal: the noun is "instance" everywhere the app says it —
UI strings, CLI output, error details, docs and comments. The wire keys
(`instance_id`, `instance_token`) and the hub route this calls move with it.

An existing cloud.json is adopted rather than refused: without the key
alias the dataclass fails to parse, which the caller swallows and reads as
"never enrolled" instead of "reconnect".

`instance_key` on a node type becomes `target_key`. It means the outside
thing a node points at, which is a different sense of the word, and keeping
both would put two meanings of "instance" in one codebase.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015YrQnKV3bnQd4K342y8tKj
This commit is contained in:
2026-08-31 10:12:01 +02:00
co-authored by Claude Opus 5
parent 6534855492
commit d01a8dad37
101 changed files with 374 additions and 375 deletions
+1 -1
View File
@@ -106,6 +106,6 @@ you what the canvas would have told you.
- MCP is not currently reachable through a [portal](../interface/portal.md)
tunnel — the proxy forwards `/api/v1/` only. Connect an agent on the same
network as the installation.
network as the instance.
- Secrets are never readable, by an agent or by anyone else. `list_secrets`
returns names.
+4 -4
View File
@@ -5,7 +5,7 @@ client of this schema, not a privileged path into the engine — so anything you
can click, you can script.
Base URL: `https://api.${DOMAIN}/api/v1`, or `http://127.0.0.1:8000/api/v1` for
a `fluksio serve` installation.
a `fluksio serve` instance.
```sh
export FLUKSIO=http://127.0.0.1:8000/api/v1
@@ -34,7 +34,7 @@ Agents authenticate differently — see [Agents over MCP](agents.md).
the tour.
It is closed in production on purpose: the schema enumerates every endpoint
the installation serves, including the paths webhook nodes mounted at
the instance serves, including the paths webhook nodes mounted at
runtime.
## Flows
@@ -230,7 +230,7 @@ draw from.
| `404` | no such flow, dashboard, run or message |
| `409` | someone else saved first — the body carries `current_version` |
| `422` | a parameter, port or binding did not typecheck |
| `503` | that subsystem is not available on this installation |
| `503` | that subsystem is not available on this instance |
A 409 on a save or a publish is not an error to retry blindly: it means the
stored version moved past the one you were editing. Re-read, merge, save again.
@@ -239,4 +239,4 @@ stored version moved past the one you were editing. Re-read, merge, save again.
The frontend's TypeScript client is generated from the OpenAPI schema
(`make generate-client`). Any OpenAPI generator will do the same for your
language — point it at `/api/v1/openapi.json` on a non-production installation.
language — point it at `/api/v1/openapi.json` on a non-production instance.
+17 -17
View File
@@ -18,10 +18,10 @@ should only *run nodes* for an engine elsewhere. It has none of the engine in
it. See [Remote workers](workers.md).
The command is two things at once: `serve`, `enroll` and `worker` *are* an
installation, while `login`, `sync`, `run`, `runs`, `artifacts`, `sweep` and
instance, while `login`, `sync`, `run`, `runs`, `artifacts`, `sweep` and
`status` talk to one that may be anywhere.
## Where an installation lives
## Where an instance lives
`.fluksio` beside your code, found the way `.git` is: from the working
directory, or any directory above it. Two repositories on one machine are
@@ -55,14 +55,14 @@ The default port moves out of the way when something already has it — 8001,
moved off: `--port 9000` on a taken 9000 fails, because something else is
there and you named it.
What it will *not* do is start a second engine for the same installation. If
What it will *not* do is start a second engine for the same instance. If
the port is held by an engine already serving this directory, it says so and
stops — one SQLite database wants one engine. Another installation's Fluksio
stops — one SQLite database wants one engine. Another instance's Fluksio
on that port is named, and the move happens as usual.
| Option | Default | What it does |
|---|---|---|
| `--data-dir PATH` | `./.fluksio` (or `$FLUKSIO_HOME`) | where this installation keeps everything |
| `--data-dir PATH` | `./.fluksio` (or `$FLUKSIO_HOME`) | where this instance keeps everything |
| `--host HOST` | `127.0.0.1` | what to bind |
| `--port PORT` | `8000`, or the next free one | what to listen on |
| `--plain` | off at a terminal | the log stream rather than the dashboard |
@@ -83,7 +83,7 @@ every other. `--gpus 1` is what serialises them.
`--enroll` with `--portal` is the one-command setup: it pairs before the engine
starts, so the connection is dialled as part of coming up rather than needing a
restart. It is skipped if the installation is already enrolled.
restart. It is skipped if the instance is already enrolled.
!!! warning "One process"
@@ -106,11 +106,11 @@ Created the admin account admin@example.com
Shown once. Change it from the dashboard.
Fluksio 0.1.0 — data in /home/you/.fluksio
API http://127.0.0.1:8000/api/v1
No portal. Pair this installation with:
No portal. Pair this instance with:
fluksio enroll <code>
```
An enrolled installation says which portal it is on instead, and notes that the
An enrolled instance says which portal it is on instead, and notes that the
dashboard is served from there rather than here.
### The dashboard
@@ -135,9 +135,9 @@ possible — and what makes `q` a way out of the screen rather than a way to
stop the engine. Running `fluksio serve` again reattaches to it.
An engine started elsewhere is adopted rather than duplicated, and can be
stopped from here only when it is this installation's own: both the pidfile
stopped from here only when it is this instance's own: both the pidfile
beside the data and a token this directory's key signed have to agree. Another
installation's engine is named and left alone.
instance's engine is named and left alone.
The screen subscribes to the engine's event bus over the same websocket a
browser uses, so a run appears the moment it starts rather than at the next
@@ -172,7 +172,7 @@ comparison refreshes when the engine says a run finished.
## `fluksio enroll`
Pairs an existing installation with a portal.
Pairs an existing instance with a portal.
```sh
fluksio enroll ABCD-1234
@@ -182,10 +182,10 @@ fluksio enroll ABCD-1234
|---|---|
| `--portal URL` | a portal of your own, instead of `https://hub.fluksio.com` |
| `--as EMAIL` | the local account a portal session arrives as |
| `--data-dir PATH` | which installation, if not the one this directory is in |
| `--data-dir PATH` | which instance, if not the one this directory is in |
Get the code from the portal under **Installations → Add installation**. It is
single-use and expires in fifteen minutes. `--as` matters when the installation
Get the code from the portal under **Instances → Add instance**. It is
single-use and expires in fifteen minutes. `--as` matters when the instance
has several superusers — without it, enrolment refuses rather than guessing.
Afterwards, `fluksio serve` dials the portal as it comes up, and keeps dialling:
@@ -353,7 +353,7 @@ answered. See [Stage caching](../concepts/runs.md#stage-caching).
`--local` boots the engine inside this process instead of talking to a served
one, so there is no `fluksio serve` terminal to keep open. It is the same
installation either way — the same `.fluksio`, the same database, artifacts
instance either way — the same `.fluksio`, the same database, artifacts
and run history — so a run made this way and a run made through a served
engine cache against each other. It always waits, because the engine it starts
lives exactly as long as the command. Starting one costs a few seconds of
@@ -376,7 +376,7 @@ A `resources` line names each machine the engine can run a node on and how much
of it is in use, plus how many nodes are queued for one. It is absent on an
engine that accounts for nothing.
The portal reads one of three ways. `no portal` means this installation was
The portal reads one of three ways. `no portal` means this instance was
never enrolled. `portal hub.fluksio.com` means the link is up. `portal
unreachable` names the error, and is the one worth acting on — the dashboard is
served from the other end, so nobody can reach it while that is showing.
@@ -524,7 +524,7 @@ Two things follow from this layout and are worth internalising:
anyone made to any flow. A run records the commit it ran at, so `git show` on
that hash is literally the code that produced the number.
**Backing up the data directory backs up the installation.** Everything else is
**Backing up the data directory backs up the instance.** Everything else is
rebuildable. Copy it while the engine is stopped, or use SQLite's online backup
for the database if it is not.
+1 -1
View File
@@ -213,7 +213,7 @@ with everything else.
## Packages
Node code runs in a virtual environment of its own, on the installation's data
Node code runs in a virtual environment of its own, on the instance's data
volume — deliberately separate from the one Fluksio itself runs on.
Declare what you import in [Modules](../interface/operations.md), or over the
+1 -1
View File
@@ -144,7 +144,7 @@ Every flow has a published version and, while you are working, a draft.
The store is a git repository — `flow.json` for the structure, `nodes/*.py` for
the code — and each save is a commit. So a flow's history is readable with
ordinary git tooling, and copying a flow between installations is copying a
ordinary git tooling, and copying a flow between instances is copying a
directory.
Saving carries the version you last saw. If someone else saved in between, you
+6 -6
View File
@@ -14,7 +14,7 @@ pip install fluksio
fluksio serve
```
That is the whole installation. No Docker, no database server, no ports to
That is the whole instance. No Docker, no database server, no ports to
open, and no login. The first run prints something like:
```text
@@ -25,7 +25,7 @@ Fluksio 0.1.0 — data in /home/you/my-research/.fluksio
API http://127.0.0.1:8000/api/v1
Nodes /home/you/my-research/.venv/bin/python
your environment, adopted. Add packages with pip.
No portal. Pair this installation with:
No portal. Pair this instance with:
fluksio enroll <code>
Signed in as admin@example.com
token in /home/you/my-research/.fluksio/client.json
@@ -39,7 +39,7 @@ below just works. `fluksio login` is for an engine somewhere *else*.
**Write that password down** anyway. It is shown once, and it is what the
dashboard asks for.
### One installation per project
### One instance per project
`.fluksio` sits beside your code, and is found the way `.git` is — from the
directory you are standing in, or any directory above it. So two repositories
@@ -135,7 +135,7 @@ environment it did not make.
### A venv of Fluksio's own
Sometimes you want the isolation instead: a shared installation, a container,
Sometimes you want the isolation instead: a shared instance, a container,
or an environment too precious to let a node's dependency near. Set
`NODE_VENV=managed` and Fluksio builds and owns one under the data directory:
@@ -761,14 +761,14 @@ A submit is around 15 ms, so calling that in a loop is a reasonable thing to do.
The pip install gives you the engine and the API, not a web interface — a
machine with no inbound route cannot serve one usefully anyway. To see the
canvas, the run history and live loss curves, pair the installation with a
canvas, the run history and live loss curves, pair the instance with a
portal, which serves the dashboard from its side:
```sh
fluksio enroll <claim-code> --portal https://hub.fluksio.com
```
Get the claim code from the portal under **Installations → Add installation**.
Get the claim code from the portal under **Instances → Add instance**.
Nothing needs to be exposed: your machine dials out and holds the connection
open. See [Accounts and the portal](../interface/portal.md).
+3 -3
View File
@@ -53,9 +53,9 @@ $EDITOR .env # FIRST_SUPERUSER, ENVIRONMENT=production
| `FIRST_SUPERUSER_PASSWORD` | leave it as `changethis` and one is generated for you |
| `ENVIRONMENT` | `production` closes the interactive API schema; `local` leaves it open |
Everything the installation owns — the database, your flows, secrets,
Everything the instance owns — the database, your flows, secrets,
artifacts, the packages your node code imports — is on one Docker volume.
Backing that volume up is backing up the installation.
Backing that volume up is backing up the instance.
??? note "Even smaller: no Docker at all"
@@ -313,5 +313,5 @@ bad it gets. See [Secrets, modules and alerts](../interface/operations.md).
- [The flow editor](../interface/flow-editor.md) — the canvas, in detail
- [Keeping state in a flow](../concepts/state.md) — running totals, debounces,
and the one rule that makes them safe
- [Accounts and the portal](../interface/portal.md) — reach the installation
- [Accounts and the portal](../interface/portal.md) — reach the instance
from outside the house without opening a port
+2 -2
View File
@@ -53,7 +53,7 @@ Some rough tells:
| **The thing you look at** | run history and loss curves | a dashboard, maybe on a wall |
If both describe you — a lab with instruments to drive *and* models to
fit — start with the data-science path. It is the smaller installation, and it
fit — start with the data-science path. It is the smaller instance, and it
grows into the other one without being reinstalled: the same engine, the same
flows, just more of them running all the time.
@@ -62,7 +62,7 @@ flows, just more of them running all the time.
Whichever door you came in:
- **Flows are files in a git repository.** Every save is a commit. You can read
the history with ordinary git, and you can copy a flow between installations
the history with ordinary git, and you can copy a flow between instances
by copying a directory.
- **Editing is separate from running.** You edit a draft; the engine keeps
running what was published until you publish.
+1 -1
View File
@@ -52,6 +52,6 @@ and a training pipeline on it.
| Drive it from Python, a shell or CI | [Code and the CLI](code/cli.md) |
| Look up a node type or a payload type | [Reference](reference/node-types.md) |
Fluksio is self-hosted by default. An installation runs offline, keeps its data
Fluksio is self-hosted by default. An instance runs offline, keeps its data
on its own disk, and never contacts anything unless you
[connect it to a portal](interface/portal.md) yourself.
+6 -6
View File
@@ -272,26 +272,26 @@ swap the device out without rebuilding what hangs there.
!!! note "If the link is wrong"
The pairing link is built from the installation's `FRONTEND_HOST`. If that
The pairing link is built from the instance's `FRONTEND_HOST`. If that
is not the address devices on your network actually reach, fix the setting
rather than the link: it is the same one password-reset mails and the OAuth
metadata are built from.
### A screen somewhere you cannot reach
Another building, someone else's network, no route in. An installation
Another building, someone else's network, no route in. An instance
[enrolled with a portal](portal.md) shows a second link,
`https://hub.${DOMAIN}/i/{installation-id}/panel`, and the same three steps
`https://hub.${DOMAIN}/i/{instance-id}/panel`, and the same three steps
work through it: the portal serves that one page without a session, forwards
the pairing calls down the tunnel, and mints the credential when you approve
the code. The pairing line then reads *via portal*.
The portal names the panel and nothing else. What the panel may read is decided
on the installation, on every call, by the same check a locally paired screen
passes. Two differences: it acts as the account the installation was enrolled
on the instance, on every call, by the same check a locally paired screen
passes. Two differences: it acts as the account the instance was enrolled
with rather than as whoever approved it, and deleting the panel stops it here
immediately while the portal's copy of the token expires on its own — which is
also why unpairing, which works on a credential this installation signed, does
also why unpairing, which works on a credential this instance signed, does
not reach a remote screen. Revoke that one at the hub.
## See also
+10 -10
View File
@@ -1,12 +1,12 @@
# The dashboard app
The web interface is a single-page app served at `app.${DOMAIN}` — or, for an
installation reached through a portal, at `${DOMAIN}/i/{installation-id}`.
instance reached through a portal, at `${DOMAIN}/i/{instance-id}`.
Either way it is the same application, and it is a client of the same REST API
you can script against.
Sign in with the account the installation was created with. On a fresh
installation that account was printed once, on the first start.
Sign in with the account the instance was created with. On a fresh
instance that account was printed once, on the first start.
## The shell
@@ -22,7 +22,7 @@ phone the sidebar collapses to a sheet.
| **Modules** | the Python packages your node code may import |
| **Alerts** | where failures get sent |
| **Admin** | users (superusers only) |
| **Search** | anything in this installation, by name |
| **Search** | anything in this instance, by name |
| **Settings** | your account, appearance, and remote access |
### Search
@@ -33,8 +33,8 @@ dashboards and the widgets on them, panels, secrets, modules, workers and alert
channels. Picking a node opens its flow with that node in focus; picking a
widget opens its dashboard.
It searches this installation. Reached through a portal, other installations
are behind **All installations** at the top of the sidebar.
It searches this instance. Reached through a portal, other instances
are behind **All instances** at the top of the sidebar.
## Home
@@ -44,7 +44,7 @@ The one screen you leave open. Four things share it.
Every flow drawn as a neuron, wired to the flows it exchanges messages with.
This is the brand mark made live, and it is also the fastest read on the
installation: a neuron pulses when its flow is running work, and its ring turns
instance: a neuron pulses when its flow is running work, and its ring turns
terracotta when the flow cannot run as written. A neuron with a problem keeps
its label showing so you can see which one it is without hovering.
@@ -70,7 +70,7 @@ Always answers, degraded or not. The tiles cover:
because their graph does not validate
- **Nodes** — how many failed to load
- **Runs running** — batch runs in flight right now, and how many are
waiting. Only on an installation that has run something
waiting. Only on an instance that has run something
- **Queue** — depth, and how old the oldest pending item is
- **Loop lag** — whether the engine's event loop is keeping up
@@ -110,8 +110,8 @@ so does Escape. The Dashboards screen works the same way.
- [Dashboards and panels](dashboards.md) — widgets, bindings, and hanging a
screen on a wall
- [Secrets, modules and alerts](operations.md) — the three screens that keep an
installation running
- [Accounts and the portal](portal.md) — reaching an installation from outside
instance running
- [Accounts and the portal](portal.md) — reaching an instance from outside
its network
## Appearance
+5 -5
View File
@@ -1,7 +1,7 @@
# Secrets, modules and alerts
Three screens that have nothing to do with each other except that an
installation you actually depend on needs all of them.
instance you actually depend on needs all of them.
## Secrets
@@ -18,7 +18,7 @@ have stored.
**Secrets** is where the values live. Add a name and a value; the value is
never shown again, and the list only ever shows names.
They are encrypted at rest with a key derived from the installation's
They are encrypted at rest with a key derived from the instance's
`SECRET_KEY`, and kept **outside** the flow repository. That matters because
flows are a git repository you may well push somewhere: what gets committed and
shared never contains a password.
@@ -35,7 +35,7 @@ authentication failure.
## Modules
Node code runs in a virtual environment of its own, on the installation's data
Node code runs in a virtual environment of its own, on the instance's data
volume — separate from the packages Fluksio itself runs on. A pin of yours can
never shadow one of ours, and vice versa.
@@ -69,7 +69,7 @@ where you say who hears about it.
| Kind | Settings |
|---|---|
| **ntfy** | server, topic, and a token for a protected topic |
| **SMTP** | an address to send to (the installation's mail settings do the rest) |
| **SMTP** | an address to send to (the instance's mail settings do the rest) |
| **Webhook** | a URL to POST to |
| **Dashboard** | a message name a notification widget reads |
@@ -126,6 +126,6 @@ are registered.
Your own account: name, email, password, and appearance (light, dark, or
follow the system).
**Remote access** is where an installation is paired with a portal, remote
**Remote access** is where an instance is paired with a portal, remote
users are admitted, and the link is cut again. That has [its own
page](portal.md).
+27 -27
View File
@@ -1,6 +1,6 @@
# Accounts and the portal
Fluksio is self-hosted by default. An installation runs offline, keeps its data
Fluksio is self-hosted by default. An instance runs offline, keeps its data
on its own disk, and never contacts anything unless you tell it to.
The **portal** is optional, and it exists to solve two specific problems:
@@ -8,10 +8,10 @@ The **portal** is optional, and it exists to solve two specific problems:
1. **Your machine has no inbound route.** A homelab behind CGNAT, a cluster
node with no open ports, a laptop. Opening one is work, and often not
allowed.
2. **You want a browser on it anyway.** A `pip install fluksio` installation
2. **You want a browser on it anyway.** A `pip install fluksio` instance
has no web server for the dashboard at all.
An enrolled installation dials *out* to the portal and holds one websocket
An enrolled instance dials *out* to the portal and holds one websocket
open. The portal serves the dashboard from its own side, and only the API calls
travel down the tunnel — so the interface loads at portal speed and your
machine stays unreachable from the internet.
@@ -19,18 +19,18 @@ machine stays unreachable from the internet.
## Enrolling
Two halves, deliberately: whoever performs the second step decides what the
installation's owner gets.
instance's owner gets.
**On the portal** (`hub.${DOMAIN}`, or [fluksio.com](https://fluksio.com) for
the hosted one): **Installations → Add installation**, give it a name, and copy
the hosted one): **Instances → Add instance**, give it a name, and copy
the code.
**On the installation**, either from the dashboard:
**On the instance**, either from the dashboard:
> **Settings → Remote access**, enter the portal URL and the code, press
> **Connect**.
or from the command line, which is the path for an installation with no web
or from the command line, which is the path for an instance with no web
interface of its own:
```sh
@@ -42,40 +42,40 @@ The code is single-use and expires in fifteen minutes.
A portal session then arrives as *that local account* — the settings screen
states this plainly, because it is the whole security model in one sentence.
Use `--as someone@example.com` to enrol as a specific local account when the
installation has several superusers.
instance has several superusers.
Once enrolled, the installation appears under **Installations** with its
Once enrolled, the instance appears under **Instances** with its
status, when it was last seen and its version. **Open** takes you to its
dashboard at `${DOMAIN}/i/{installation-id}`.
dashboard at `${DOMAIN}/i/{instance-id}`.
## What the portal can and cannot do
The portal holds one credential for your installation and proxies requests down
the tunnel. What those requests may do is decided **on the installation**, by
The portal holds one credential for your instance and proxies requests down
the tunnel. What those requests may do is decided **on the instance**, by
the same checks a local session passes.
The trust anchor is a signing keypair on the portal. Every installation pins
The trust anchor is a signing keypair on the portal. Every instance pins
its public half at enrolment and rejects anything else — which is what stops a
hijacked DNS entry or a mis-issued certificate from impersonating the portal.
## Letting someone else in
Anyone else on the portal reaches your installation only if a superuser there
Anyone else on the portal reaches your instance only if a superuser there
admits them, and they arrive as a local user of their own rather than as you.
1. **They**: **Installations → Join an installation**, and copy the code. It is
1. **They**: **Instances → Join an instance**, and copy the code. It is
bound to their portal account and expires in fifteen minutes.
2. **You**, on the installation: **Settings → Remote access → Add remote
2. **You**, on the instance: **Settings → Remote access → Add remote
user**, and enter the code.
3. They now see the installation under **Installations**, marked *Shared by*,
3. They now see the instance under **Instances**, marked *Shared by*,
with **Open** and nothing else. Renaming, re-keying and removing stay with
you.
The installation redeems that code against the portal using its own credential.
The instance redeems that code against the portal using its own credential.
A portal session cannot do this — which is what stops somebody you let in from
letting others in.
On the installation they appear under **Admin → Users**, badged *Portal*, never
On the instance they appear under **Admin → Users**, badged *Portal*, never
a superuser and with no password.
## Cutting it off
@@ -84,29 +84,29 @@ a superuser and with no password.
|---|---|---|
| The portal | **New code** | rotates the credential and drops the current link |
| The portal | **Remove** | deletes the registration and cuts the connection |
| The installation | **Disconnect** | unilateral and immediate — the portal's tokens stop verifying here whatever the portal still has on file |
| The installation | delete a user under **Admin → Users** | that one person, immediately, independent of the portal |
| The instance | **Disconnect** | unilateral and immediate — the portal's tokens stop verifying here whatever the portal still has on file |
| The instance | delete a user under **Admin → Users** | that one person, immediately, independent of the portal |
**New code** also cuts every credential the portal minted for this installation,
**New code** also cuts every credential the portal minted for this instance,
including [wall panels paired through it](dashboards.md#a-screen-somewhere-you-cannot-reach).
The installation's own **Disconnect** is the one to reach for if you are ever
The instance's own **Disconnect** is the one to reach for if you are ever
unsure: it does not need the portal's cooperation.
## Running your own portal
The portal is the `index` stack's `hub` service — accounts, the registry of
connected installations, and the websocket each one dials in on. Two things
connected instances, and the websocket each one dials in on. Two things
about it are load-bearing:
- **It runs a single process.** It keeps its attached installations in the
- **It runs a single process.** It keeps its attached instances in the
memory of the process holding their sockets, so a second worker would answer
for links it does not hold. Scaling out needs a routing layer first.
- **Back up the signing keypair with the database.** Replacing it forces every
installation to be enrolled again.
instance to be enrolled again.
Websocket upgrades must be enabled on the `hub` hostname in whatever proxy
fronts it. Without them every installation sits in a reconnect loop and the
fronts it. Without them every instance sits in a reconnect loop and the
portal shows them all offline.
## See also
+1 -1
View File
@@ -5,7 +5,7 @@
> same engine serves two shapes of work: live flows that never end (buildings,
> labs, homelabs) and batch runs that finish and leave a record (experiments,
> ML pipelines, CI-style jobs). Self-hosted by default; an optional portal
> exists only to reach an installation that has no inbound route.
> exists only to reach an instance that has no inbound route.
## Getting started
- [Pick your starting point](/getting-started/): the two setup paths and how to choose
+4 -4
View File
@@ -1,7 +1,7 @@
# Configuration
Every setting comes from the environment, or from an env file. Which file
depends on how the installation was started:
depends on how the instance was started:
| Started with | Reads |
|---|---|
@@ -36,7 +36,7 @@ what the container images do to pin everything onto `/data`.
| `managed` | a venv the engine builds under `DATA_DIR` and owns, which the Modules screen installs into with `uv pip sync`. The container images set this: the venv in them holds the app and nothing of anybody else's. |
| a path | that interpreter, or that venv, whatever it is. |
An installation that already has a managed venv keeps it on upgrade under
An instance that already has a managed venv keeps it on upgrade under
`auto`, because it may hold packages somebody installed on purpose.
!!! warning "The four files that must be on persistent storage"
@@ -112,10 +112,10 @@ remember it is fixed at build time: changing it means rebuilding that image.
`delay` with a cron expression fires on local time. Left at `UTC`, "off at
02:00" means two in the morning UTC, which in most of the world is neither two
o'clock nor the same hour in summer as in winter. Set it to where the
installation is.
instance is.
`production` closes `/docs`, `/redoc` and the OpenAPI document, because the
schema enumerates every endpoint the installation serves — including the paths
schema enumerates every endpoint the instance serves — including the paths
webhook nodes mounted at runtime. It also turns a `changethis` secret from a
warning into a refusal to start.
+2 -2
View File
@@ -5,7 +5,7 @@ editor generates from its parameter schema, so they all behave the same way.
Anything here could be written as a **Function** node — that is what the
function node is for. These exist because the same handful of shapes account
for most of a real installation, and a rule you fill in is easier to read on a
for most of a real instance, and a rule you fill in is easier to read on a
canvas, and to change, than five lines of code repeated eighty times.
`GET /flows/node-types` returns this list with each type's full parameter
@@ -138,7 +138,7 @@ thing configured elsewhere.
| `start_delay` | `1.0` | how long to wait before that first emission |
The scheduler: a `cron` expression here is what makes a flow run by the clock.
It is also the most-placed node in a real installation — mostly as a button
It is also the most-placed node in a real instance — mostly as a button
someone presses.
### Delay & schedule