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:
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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).
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user