Quick Run with the Kit Image
The Kit image (fluxify-kit) bundles everything Fluxify needs into a single container: the admin API, the request worker, the dashboard, the AI gateway, and a built-in proxy. It also ships its own database, cache, and event bus, so you can start the whole thing with one command and nothing else installed.
One container, one port, one command — for prototypes and testing only.
WARNING
Not for production, not even on a single machine. Use the Production Setup instead — it separates the control plane from replicated workers so you can scale request handling independently.
What you get
| Item | Value |
|---|---|
| Containers to run | 1 (or 4, if you supply your own database, cache, and event bus) |
| Workers | A production worker serving every project by default, and a development worker — both always run |
| Public port | 8080 |
| Best for | Prototypes and testing only. Not production. |
| Scaling | Vertical only (bigger machine) |
Traffic enters on port 8080 and is routed for you:
| URL | Goes to |
|---|---|
http://localhost:8080/_/admin/ui | Dashboard (visual editor) |
http://localhost:8080/_/admin/api | Admin REST API |
http://localhost:8080/_/admin/api/openapi/ui | API documentation |
http://localhost:8080/ | Your published workflows & custom endpoints |
http://localhost:8080/_sandbox/<id>/… | A sandbox, served by the development worker |
http://localhost:8080/_/dev/… | Your routes on the development worker, with the development token |
Two ways to run it
Pick one. Both use the same image.
| Bundled (recommended for trials) | Bring your own services | |
|---|---|---|
| Command | docker run | docker compose |
| Database, cache, event bus | Included in the container | You supply them |
| Setup | One command, no config file | Copy and edit an environment file |
| Good for | Trying Fluxify out today | Keeping data in a database you manage |
The image decides automatically: if you tell it where to find a database, cache, or event bus, it uses yours. If you don't, it starts its own.
Option A — One command
Nothing to install, no configuration file:
docker run -d --name fluxify \
-p 8080:8080 \
-v fluxify_data:/data \
-e [email protected] \
-e SEED_USER_PASSWORD=ChangeThisPassword123! \
ghcr.io/fluxify-rest/fluxify-kit:nightlyThen open http://localhost:8080/_/admin/ui and log in with the email and password you just set.
NOTE
The kit uses http://localhost:8080 as its public address by default. That one variable, SERVER_URL, is also Better Auth's base URL and the trusted origin. If you publish a different host port — for example -p 9090:8080 — set SERVER_URL to the address you open. See Changing the port.
IMPORTANT
SEED_USER_EMAIL and SEED_USER_PASSWORD are required and have no defaults. They create the first administrator account, and nothing else can create it for you. A brand-new instance refuses to start without them rather than starting up with no way to log in. The password must be at least 8 characters.
About that -v fluxify_data:/data
Everything the kit stores lives in /data: your projects and routes, the event history, and the security keys it generates the first time it starts.
Don't skip the volume. Without it, removing the container throws all of that away.
WARNING
On first start the kit generates its own encryption and session keys and saves them in /data. Back this up. If you lose it, saved credentials — database passwords, integration keys — can no longer be read, even with the same projects restored.
Changing the port
If 8080 is taken, map a different one on the left-hand side and tell Fluxify its public address:
docker run -d --name fluxify \
-p 9090:8080 \
-v fluxify_data:/data \
-e SERVER_URL=http://localhost:9090 \
-e [email protected] \
-e SEED_USER_PASSWORD=ChangeThisPassword123! \
ghcr.io/fluxify-rest/fluxify-kit:nightlyOption B — Bring your own database, cache, and event bus
Use this when you want your data in a database you manage and back up yourself.
Step 1 — Create your .env
Copy docker/kit/env.example to docker/kit/.env next to the compose file:
cp docker/kit/env.example docker/kit/.envAt minimum verify these values:
#====================== ENVIRONMENT ======================
NODE_ENV=production
ENVIRONMENT=production
#====================== YOUR OWN SERVICES ======================
# Setting these three switches off the built-in copies.
PG_URL=postgres://postgres:postgres@postgres:5432/fluxify_alpha
REDIS_HOST=valkey
REDIS_PORT=6379
NATS_URL=nats://nats:4222
NATS_TOKEN=fluxify_nats_token
#====================== THE PROJECT THIS KIT SERVES ======================
# `*` serves every project and picks up new ones without a restart. Set a
# project id to pin the worker to one project.
WORKER_PROJECT_ID=*
INTEGRATION_TIMEOUT_POLICY_IN_SEC=450
#====================== SECURITY & KEYS ======================
MASTER_ENCRYPTION_KEY=<openssl rand -base64 32>
BETTER_AUTH_SECRET=<openssl rand -base64 32>
#====================== FIRST-RUN ADMIN ======================
[email protected]
SEED_USER_PASSWORD=ChangeThisPassword123!
SEED_USER_NAME=Admin UserWARNING
Back up MASTER_ENCRYPTION_KEY. If you lose or change it after storing data, every saved credential becomes unreadable.
NOTE
When you supply your own services you must also supply your own MASTER_ENCRYPTION_KEY and BETTER_AUTH_SECRET. The kit only generates those for you in bundled mode, where it has somewhere of its own to keep them.
Generate your secret keys
Use this generator to create secure values for MASTER_ENCRYPTION_KEY and BETTER_AUTH_SECRET, then paste them into your .env:
Step 2 — Start the stack
docker compose -f docker/kit/docker-compose.yml up -dThis starts four containers: Fluxify plus the database, cache, and event bus. Database setup runs automatically on first boot.
Step 3 — Open the dashboard
http://localhost:8080/_/admin/uiLog in with the seed admin credentials from your .env.
Serving your projects
This part applies to both options.
The request worker starts with the kit and serves every project by default (WORKER_PROJECT_ID=*). Create a project in the dashboard, save a route, and it is live at http://localhost:8080/ — there is no project id to copy and no restart.
TIP
The catch with *: two projects that define the same path — say both have a /users endpoint — collide, and only one of them answers. Fine while you have one project, which is the usual case for a trial. Give a project its own subdomain (Project settings → General) to keep equal paths apart.
To pin the worker to one project instead:
- Copy the project id from the project's settings page.
- Set
WORKER_PROJECT_IDto that id — indocker/kit/.envfor Option B, or as another-e WORKER_PROJECT_ID=...for Option A. - Start the container again with the new value.
Saving a route in the editor publishes it to the worker in place — no restart and no redeploy. See Request Lifecycle for what happens on save.
To opt into experimental CPU-stall protection, set the project setting experimental.workerTimeouts.enabled to true. The worker receives that change immediately; no restart is required.
NOTE
One kit serves one project when pinned, or every project under * (the default). To serve several projects properly, move to the Production Setup, which runs a worker group per project.
The development worker
The kit also starts a second worker for the developmentenvironment. It needs no setup: it serves every project, so it runs from the very first start, before you have created one.
| Production worker | Development worker | |
|---|---|---|
| Serves | Every project by default; one project when WORKER_PROJECT_ID is pinned | Every project |
| Port (inside the container) | 5600 | 5602 |
| Health probe | 5601 | 5603 |
Reached through port 8080 | Yes | Only /_sandbox and /_/dev |
Port 8080 sends /_sandbox and /_/dev to the development worker and everything else to the production worker, so sandboxes, the playground, call_route and Run work with no setting. A path that only starts with the same letters, such as /_devices, still goes to the production worker. This holds on a project's subdomain too. A project with a subdomain answers /_sandbox and /_/dev only on that subdomain, so keep the subdomain's name pointing at port 8080. The development worker does not count against your edition's worker limit.
The admin calls the development worker through the same port 8080. A deployment where the admin cannot reach that public address sets PROXY_URL to the proxy's own address, for example http://localhost:8080 for the kit's Caddy — never to a single worker.
WARNING
Don't set FLUXIFY_ENV in the kit's .env or with -e. The kit sets it on the second worker only. Setting it for the whole container would turn your production worker into a development one.
Connecting AI clients (MCP)
Fluxify has an MCP server, so AI apps and coding agents can work with your projects. Point the client at:
http://localhost:8080/_/admin/mcpThe client signs in as a Fluxify user, and you approve it in the browser. It gets the same access that user has. For sign-in to work, these addresses go to Fluxify on the same port as everything else:
| URL | What it is |
|---|---|
/_/admin/mcp | The MCP server |
/.well-known/oauth-protected-resource | Tells the client where to sign in |
/.well-known/oauth-authorization-server | The sign-in details |
Only paths starting with /.well-known/oauth- are taken for this. Any other /.well-known/... path still reaches your own routes.
IMPORTANT
Cloud AI apps need a public HTTPS address. claude.ai and ChatGPT connect from their own servers, not from your computer, so they can't reach localhost or a private network. Your instance must be reachable from the internet over https://. Apps running on your own machine can use http://localhost:8080.
WARNING
Use HTTPS on any address other than localhost. On such an address, Fluxify tells MCP clients to sign in over https://, even when it is served over plain http://. Without HTTPS, sign-in fails.
Check: replace <url> with your address.
curl -i -X POST <url>/_/admin/mcp # 401, with a WWW-Authenticate header
curl <url>/.well-known/oauth-protected-resource/_/admin/mcp # JSON
curl <url>/.well-known/oauth-authorization-server/_/admin/api/auth # JSONThe 401 is expected: it means the MCP server is up and asks the client to sign in. The JSON lists your public address. If it shows another one, fix SERVER_URL (and TRUSTED_ORIGINS if the portal is served on a different origin).
Plugins
A project can add a plugin by upload, npm, a link to a .tgz, or a folder. Everything runs inside the one container, so there is nothing to mount: the folder source reads /data/plugins, which is part of your fluxify_data volume. Copy a built plugin (a subfolder with its package.json, fluxify.json and dist/) there and pick it under Plugins, From a folder.
Links only work for hosts an instance admin trusts, which they set through the instance settings API (see Adding a plugin). Every plugin waits for a creator to approve it.
Upgrading
Option A:
docker pull ghcr.io/fluxify-rest/fluxify-kit:nightly
docker rm -f fluxify
# then run the same `docker run` command again — your /data volume is reusedOption B:
docker compose -f docker/kit/docker-compose.yml pull
docker compose -f docker/kit/docker-compose.yml up -dAny required database updates run automatically at startup. If one fails, the container stops and its log says database migration failed; the update is all or nothing, so your data is left as it was. Back up before upgrading.
WARNING
In bundled mode, a major upgrade of the built-in database cannot be applied to data already on disk. Upgrades that change it are announced in the release notes, and the safe path is to export what you need before upgrading. This is one of the reasons the kit isn't meant for production — see Production Setup.
Troubleshooting
Container exits immediately, log says an admin email or password is required The first administrator account can only come from SEED_USER_EMAIL and SEED_USER_PASSWORD. Set both (password 8+ characters) and start it again.
Container exits immediately, other causes Check the logs: docker logs fluxify (Option A) or docker compose -f docker/kit/docker-compose.yml logs fluxify (Option B). In Option B the usual cause is a bad PG_URL, or a NATS_TOKEN that doesn't match the one given to the event bus container.
The container stops when one part of it fails That's deliberate. If any internal service dies, the whole container exits so your restart policy brings it back, instead of leaving it running and quietly broken. The log line naming the failed service is the last one printed.
Can't log in after first run The seed admin is created only on the very first boot, against an empty database. If you changed the values afterwards, they had no effect — reset the password from the dashboard, or start over with a fresh volume. If the first start failed before the login was created, restarting retries it.
Everything was working, then a restart lost all my projects You most likely ran without -v fluxify_data:/data. Data lives in that volume; without it, removing the container discards everything.
Port 8080 already in use Map a different host port and set SERVER_URL to match. See Changing the port.
Requests to / return 502 Bad Gateway The request worker isn't running yet or has died. Check docker logs fluxify | grep worker; the kit stops the container when any internal service exits. See Serving your projects.
Requests to / return 404 Route not found The worker is running but doesn't have that route. Confirm the route is marked active and, if you pinned WORKER_PROJECT_ID, that it belongs to that project; then save it again to publish it.
Routes save fine but never go live The event bus needs JetStream enabled. The bundled copy and the supplied compose file both do this already; if you swapped in your own, start it with -js.
Fluxify exits with "NATS server … is too old" Fluxify needs NATS 2.14 or newer; scheduled triggers rely on it. The bundled copy is new enough. If NATS_URL points at your own NATS, upgrade it.
