From d3db58310b939f03ed65a27d6b50407696efb454 Mon Sep 17 00:00:00 2001 From: stroblme Date: Sat, 22 Aug 2026 09:49:50 +0200 Subject: [PATCH] Getting started: reach the app by address, without DNS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The guide asked for a hostname and served the interface on `app.${DOMAIN}` with the API on `api.${DOMAIN}` — which is not what someone with a box in a cupboard sets up, and could not be made to work by typing an address into a browser. `compose.lan.yml` already solves it for the dev stack; the same file layers onto the production one, so the guide now opens with that and keeps the hostname as the other option. The reference gained the setting behind it. `VITE_API_URL` is a build argument of the frontend image rather than something the stack reads, which is worth saying once: empty means the interface addresses the API relative to whatever origin served it, so one image answers on an address, a hostname and an ssh tunnel alike, and no CORS list has to be kept in step. Verified against the production compose layered with `compose.lan.yml`: the page, `/api` on the same port, a cross-origin-free login, the flow websocket upgrading through nginx, and `/docs` still refused there. Co-Authored-By: Claude Opus 5 (1M context) --- docs/getting-started/facility-automation.md | 79 ++++++++++++++++----- docs/reference/configuration.md | 20 ++++++ 2 files changed, 82 insertions(+), 17 deletions(-) diff --git a/docs/getting-started/facility-automation.md b/docs/getting-started/facility-automation.md index 7801fef..2f83b35 100644 --- a/docs/getting-started/facility-automation.md +++ b/docs/getting-started/facility-automation.md @@ -27,28 +27,28 @@ all part of the same process, editing the same graph. ## Prerequisites - Docker and Compose v2 on the host -- A hostname you can point at it. `fluksio.local`, a subdomain, or just - `localhost` if you only ever reach it from that machine +- The address you will type into a browser. On a home network that is the + server's own address — `192.168.1.50` — and nothing else is needed. A + hostname is optional, and covered below - Optionally: an MQTT broker and an InfluxDB you already run. If not, the stack can start both for you -## Bring up the stack +## Configure it -Clone the app repository and start it: +Clone the app repository and write its one configuration file: ```sh git clone https://git.stroblme.de/Fluksio/app.git ~/fluksio cd ~/fluksio cp .env.example .env -$EDITOR .env # DOMAIN, FIRST_SUPERUSER, ENVIRONMENT=production -make up +$EDITOR .env # FIRST_SUPERUSER, ENVIRONMENT=production ``` `.env` is the whole configuration. The four settings that matter on day one: | Setting | What it does | |---|---| -| `DOMAIN` | the hostname everything is served under; the SPA lands on `app.${DOMAIN}` and the API on `api.${DOMAIN}` | +| `DOMAIN` | the hostname everything is served under, if you use one. Left alone it only names the issuer that agents authenticate against | | `FIRST_SUPERUSER` | the account you sign in with | | `FIRST_SUPERUSER_PASSWORD` | leave it as `changethis` and one is generated for you | | `ENVIRONMENT` | `production` closes the interactive API schema; `local` leaves it open | @@ -57,14 +57,6 @@ Everything the installation 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. -!!! tip "Reverse proxy" - - The stack emits Traefik labels and ships a Traefik you can bring up - alongside it (`docker/compose.traefik.yml`). If you already run Nginx - Proxy Manager or Caddy, attach it to the `proxy` network instead and - forward `app.${DOMAIN}` → `fluksio-app:80` and `api.${DOMAIN}` → - `fluksio-api:8000`. - ??? note "Even smaller: no Docker at all" `pip install fluksio && fluksio serve` gives you the same engine with no @@ -74,8 +66,61 @@ Backing that volume up is backing up the installation. serves the dashboard for you. Good for a Raspberry Pi that only runs flows; less good as your main instance. -Open `http://app.${DOMAIN}` and sign in. You should be looking at Home: an -empty brain graph, a health summary, and a flow list with nothing in it. +## Reach it from another machine + +Start it one of two ways, depending on whether you have a hostname to point at +it. Neither is more supported than the other. + +### On your own network, by address + +The usual case: the box is in a cupboard at `192.168.1.50` and you open it from +a laptop. Layer `docker/compose.lan.yml` on, which publishes the interface on a +port and serves the API from that same origin: + +```sh +APP_PORT=8080 docker compose -p fluksio-app --env-file .env \ + -f docker/compose.yml -f docker/compose.lan.yml up -d --build +``` + +Open `http://192.168.1.50:8080`. That one address is the whole application — +the interface, the API under `/api`, and the websocket that puts live values on +the canvas. + +Nothing in that URL is configured anywhere. The interface is built to address +the API relative to whatever origin served the page, so the same containers +answer to the machine's address, to a hostname you add later, and through an +ssh tunnel, without being rebuilt. It is also why no CORS list needs +maintaining: the browser is talking to one origin. + +!!! danger "This is your network, not the internet" + + A published port is plain HTTP with no certificate. Between your own + machines that is fine, and it is not something to forward from a router. To + reach the house from outside, put a reverse proxy with TLS in front of it — + or [pair it with a portal](../interface/portal.md), which needs no inbound + route at all. + +### With a hostname, behind a reverse proxy + +If you have DNS — or want certificates — set `DOMAIN` and run `make up` +instead. The interface is then served on `app.${DOMAIN}` and the API on +`api.${DOMAIN}`, and nothing is published on a host port. + +The stack emits Traefik labels and ships a Traefik you can bring up alongside +it (`docker/compose.traefik.yml`). With Nginx Proxy Manager or Caddy instead, +attach it to the `proxy` network and forward `app.${DOMAIN}` → +`fluksio-app:80` and `api.${DOMAIN}` → `fluksio-api:8000`. + +!!! tip "Developing on the same machine" + + `make dev-lan` is the same idea for the integrated dev stack — the app on + `http://:8080`, `APP_PORT` to move it. `make dev` rebuilds without + the published port, so re-run `make dev-lan` after one. + +## Sign in + +Open whichever address you chose. You should be looking at Home: an empty brain +graph, a health summary, and a flow list with nothing in it. ## Your first flow diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 63ec324..1adb450 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -56,6 +56,26 @@ on. | `FRONTEND_HOST` | `http://localhost:5173` | used in mails, OAuth metadata and panel pairing links | | `BACKEND_CORS_ORIGINS` | `[]` | comma-separated; `FRONTEND_HOST` is always allowed | +## Where the interface looks for the API + +The dashboard is a static bundle, so this one is a **build** argument of the +`frontend` image rather than a setting the running stack reads. + +| Argument | Used by | Effect | +|---|---|---| +| `VITE_API_URL` | `frontend` at build time | the address the interface calls | + +Empty is the useful value: the interface then addresses the API relative to +whichever origin served the page, so one image answers on a hostname, on a +`http://:`, and through an ssh tunnel alike — and no origin has +to be added to `BACKEND_CORS_ORIGINS`, because there is only one. +`docker/compose.lan.yml` builds it that way and puts an `/api` proxy in front +of the backend to complete it; see +[getting started](../getting-started/facility-automation.md#on-your-own-network-by-address). + +Set it to an absolute URL only when the API genuinely lives somewhere else, and +remember it is fixed at build time: changing it means rebuilding that image. + !!! danger "Rotating `SECRET_KEY`" The secrets store is encrypted with a key derived from it. Change it and