Node-RED, hosted properly.

Openflow is a multi-tenant Node-RED platform you run yourself. One Docker container per instance. One subdomain per instance. Magic-token SSO, MQTT included, an AI assistant in the toolbar. No vendor lock, no per-seat tax. Yours to keep.

Star on GitHub
$ curl -L openflow.ing/install | sh
read the docs
$ openflow list live
name status memory project uptime wfengine running 2.0 GB integrations 14d 02:31 integrations running 1.2 GB integrations 14d 02:30 sandbox-dev stopped dev archive running 512 MB archive 6d 18:09
[ 01 ]

what makes it different

01 / isolation

One container per instance, always.

Other Node-RED platforms run a shared editor and proxy tenants into it. Openflow runs one Docker container per instance, named nodered-<subdomain>, on its own network alias with its own /data volume.

Crashes don't cascade. Memory limits are enforced. A misbehaving flow can only break itself.

02 / authentication

Magic-token SSO, no Node-RED passwords.

Sign into Openflow once. Click Launch on any instance. The manager mints a single-use token, the editor opens authenticated, and subsequent sessions ride a long-lived per-instance master token in an HttpOnly cookie. Browser-restart safe.

03 / broker

EMQX included, namespaced per project.

Every instance gets OPENFLOW_MQTT_* environment variables wired to a shared EMQX broker. Topics are mountpoint- prefixed by project, so two tenants cannot read each other's traffic even when the topic strings look identical.

04 / assistant

An AI helper in the editor toolbar.

A Claude-backed assistant sits next to your flows. It reads the active flow, calls one tool to add, rewire, or delete nodes, and draws each node as the model commits to it. Not one silent dump at the end.

[ 02 ]

how it works

From the request landing at nginx to the user editing a flow, here's the full path. Nothing exotic, on purpose.

REQUEST

Wildcard subdomain hits nginx

wfengine.example.com resolves to the box. Nginx terminates TLS with a wildcard cert.

server_name ~^([^.]+).example.com$
proxy_pass to nodered-$subdomain:1880
ROUTE

Docker DNS resolves to the right container

Each instance runs as nodered-<subdomain> on the openflow-network bridge, with any alias slugs attached as additional network aliases.

docker bridge: openflow-network
aliases: nodered-wfengine, nodered-integrations
AUTH

Node-RED checks the magic token

The editor's settings.js intercepts the launch token and promotes the per-instance master token into a long-lived cookie. Restarts keep the user signed in.

tokens() resolves MAGIC in memory
cookie: openflow_token=MAGIC; 30d
DATA

The flow uses MQTT and Postgres like any other Node-RED

MQTT nodes are pre-wired to the shared EMQX broker. Project topic mountpoints isolate tenants. Snapshots and backups happen on a schedule from the manager.

EMQX mountpoint: ff/<projectId>/
backups: nightly tar.gz of /data
[ 03 ]

get it running

Pick the shape that matches your infrastructure. The reference deploy is a single host running Docker, Postgres, and the manager.

RECOMMENDED

Single host (Docker Compose)

One box, Docker, Postgres, the manager, nginx. Reference deploy.

$ git clone github.com/skaag/openflow
$ cd openflow && cp .env.example .env
# edit .env: ROOT_DOMAIN, SESSION_SECRET
$ docker compose up -d
FAST

One-line install

Curl-pipe-sh for a fresh Ubuntu host. Installs Docker, Postgres, nginx, the manager.

$ curl -L openflow.ing/install | sh
# asks for: ROOT_DOMAIN, admin email
# brings up the manager on port 80/443
CLUSTER

Kubernetes (Helm)

For multi-node clusters. Postgres external. ALB or ingress in front.

$ helm repo add openflow \
    https://openflow.ing/charts
$ helm install openflow openflow/openflow \
    -f values.yaml
[ 04 ]

built on

Openflow doesn't reinvent any of the hard parts. It wires together the projects that already solve them, gives them a UI, and stays out of the way.

Take an evening, give it the box, see if it earns its keep.