One image for the whole app: engine, API and dashboard on one port
The backend image now builds the SPA and serves it on the API's own origin (fluksio/spa.py), so an instance is a single container with no proxy, DNS, port 80 or .env: `docker compose up -d` with the new compose.yml runs it on localhost:8080. It starts on fluksio serve (persisted secret key, first admin printed once) and brings its own Redis when REDIS_HOST is unset. Slimmer: python:3.13-slim, no dev group, uv once, fastapi without the cloud CLI. Optional features are per-feature extras (mqtt, influx, email, sentry, ml, server for all) picked with the EXTRAS build argument; numpy moved to `ml`. ffmpeg left the image for imageio-ffmpeg via the Modules screen. The operator stack runs the same image with app. and api. routed to it; the nginx frontend service, the LAN nginx proxy and DOMAIN in the backend are gone, and the MCP issuer is FRONTEND_HOST. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -42,9 +42,10 @@ Docker stores instance data under `/data` on the `app-flow-data` volume.
|
||||
Docker uses `managed`. When Fluksio adopts your own venv, the Modules screen
|
||||
is read-only; install packages into that environment yourself.
|
||||
|
||||
Back up the whole data directory and the persistent `SECRET_KEY`. In Docker,
|
||||
keep `.env` and `app-flow-data`; back up `app-redis-data` too when preserving
|
||||
live state. Compose prefixes volume names with the project name `fluksio-app`.
|
||||
Back up the whole data directory and the persistent `SECRET_KEY`. The single
|
||||
container keeps both, and its Redis, on the `/data` volume. The operator stack
|
||||
under `docker/` keeps `.env` and `app-flow-data`, plus `app-redis-data` for
|
||||
live state. Compose prefixes volume names with the project name.
|
||||
Keep runtime files on persistent storage so rebuilds preserve credentials,
|
||||
pairings and subscriptions.
|
||||
|
||||
@@ -52,13 +53,15 @@ pairings and subscriptions.
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
|---|---|---|
|
||||
| `REDIS_HOST` | unset | unset uses memory; a Redis host enables persistent flow state |
|
||||
| `REDIS_HOST` | unset | unset uses memory, or the image's own Redis in Docker; a Redis host enables persistent flow state |
|
||||
| `REDIS_PORT` | `6379` | Redis port |
|
||||
|
||||
Live state includes message values, node memory and queued work. In-memory
|
||||
state is lost on restart. The Docker stack uses Redis with append-only
|
||||
persistence on its own `app-redis-data` volume. Its default sync policy may
|
||||
lose about a second of recent writes after an unclean shutdown.
|
||||
state is lost on restart. The Docker image starts a Redis of its own with
|
||||
append-only persistence in `/data/redis` whenever `REDIS_HOST` is unset. Set
|
||||
`REDIS_HOST` to use an external one instead, as the operator stack does with
|
||||
its `app-redis-data` volume. The default sync policy may lose about a second of
|
||||
recent writes after a power cut.
|
||||
|
||||
## Accounts and access
|
||||
|
||||
@@ -68,8 +71,7 @@ lose about a second of recent writes after an unclean shutdown.
|
||||
| `ACCESS_TOKEN_EXPIRE_MINUTES` | `11520` (8 days) | session-token lifetime |
|
||||
| `FIRST_SUPERUSER` | unset | initial administrator email; the CLI creates an account if needed |
|
||||
| `FIRST_SUPERUSER_PASSWORD` | unset | initial password; the CLI generates and prints one if needed |
|
||||
| `DOMAIN` | `localhost` | API hostname and OAuth issuer; Docker also uses it for routing |
|
||||
| `FRONTEND_HOST` | `http://localhost:5173` | interface URL for links and metadata |
|
||||
| `FRONTEND_HOST` | `http://localhost:5173`, `http://localhost:8000` in Docker | the address people and devices reach the instance at; panel links, mails and the OAuth issuer use it |
|
||||
| `BACKEND_CORS_ORIGINS` | `[]` | allowed origins, as comma-separated URLs or a JSON list; `FRONTEND_HOST` is also allowed |
|
||||
| `FORWARDED_ALLOW_IPS` | `127.0.0.1` | trusted proxies; Docker adds `172.16.0.0/12` |
|
||||
| `SIGNUP_ENABLED` | `false` | allows account creation from the login page; otherwise use **Admin → Users** |
|
||||
@@ -79,32 +81,31 @@ lose about a second of recent writes after an unclean shutdown.
|
||||
Changing `SECRET_KEY` signs everyone out and makes existing encrypted
|
||||
secrets unreadable. Back it up with your data.
|
||||
|
||||
## Interface API address
|
||||
## Interface address
|
||||
|
||||
`VITE_API_URL` is a frontend **build argument**, so changing it requires
|
||||
rebuilding the frontend image.
|
||||
|
||||
| Setup | Value |
|
||||
|---|---|
|
||||
| Production Docker | set `.env` to `https://api.<your-domain>` |
|
||||
| `make dev-local` | overlay sets `http://api.localhost` by default |
|
||||
| `make dev-lan` | overlay sets an empty value, using `/api` on the page's own origin |
|
||||
|
||||
Without an explicit value, the production Compose file falls back to
|
||||
`https://api.${DOMAIN}`. Set `FRONTEND_HOST` and `BACKEND_CORS_ORIGINS` to
|
||||
match your deployment as well; `make init` generates secrets, not deployment
|
||||
URLs.
|
||||
|
||||
The LAN overlay also configures nginx to proxy `/api` and WebSocket requests
|
||||
to the backend. An empty value needs that proxy when the frontend and backend
|
||||
are served separately. See [facility automation](../getting-started/facility-automation.md#run-it-long-term)
|
||||
for deployment settings.
|
||||
The image serves the interface and the API on one origin, so the interface
|
||||
calls the API as a path on whatever address served it. One build works behind
|
||||
any port, hostname or reverse proxy. `FRONTEND_DIST` points at the built
|
||||
interface and is set by the image. A checkout leaves it empty and runs the Vite
|
||||
dev server, which needs its origin in `BACKEND_CORS_ORIGINS`.
|
||||
|
||||
## Image options
|
||||
|
||||
`WITH_FFMPEG=true` in `.env` installs `ffmpeg` into the backend image on the
|
||||
next build, for node code that transcodes video. It is off by default because
|
||||
it adds about 400 MB.
|
||||
The `EXTRAS` build argument picks the optional features built into the image,
|
||||
comma separated. Empty, the default, is the minimal engine.
|
||||
|
||||
| Extra | Adds |
|
||||
|---|---|
|
||||
| `mqtt` | the MQTT node |
|
||||
| `influx` | the InfluxDB node |
|
||||
| `email` | outbound mail, such as password resets |
|
||||
| `sentry` | error reporting to `SENTRY_DSN` |
|
||||
| `ml` | numpy, for the `mlp` node |
|
||||
| `server` | all of the above |
|
||||
|
||||
A node whose extra is missing says so on the canvas. The same names work as
|
||||
pip extras, such as `pip install 'fluksio[mqtt]'`. Connector packages built
|
||||
with `make connectors` are installed into the image too.
|
||||
|
||||
## Environment
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@ settings in the node panel; use a **Function** node for your own Python.
|
||||
`GET /flows/node-types` returns this list with each type's full parameter
|
||||
schema, including any [connectors](#connectors) installed on your instance.
|
||||
|
||||
MQTT and InfluxDB need `pip install 'fluksio[server]'` on a Python installation.
|
||||
The Docker image includes these dependencies. Run the broker and database
|
||||
separately, or use the development stack's test services.
|
||||
MQTT and InfluxDB need their [extras](configuration.md#image-options): `mqtt`
|
||||
and `influx` in the image's `EXTRAS`, or `pip install 'fluksio[mqtt,influx]'`
|
||||
on a Python installation. Run the broker and database separately.
|
||||
|
||||
## Function
|
||||
|
||||
|
||||
Reference in New Issue
Block a user