From 6a6d5747a38a806585b83dea4d752b4a3de5e161 Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 3 Oct 2026 23:33:51 +0200 Subject: [PATCH] nodered: the runtime serves its tools, and its mqtt step is a run-once process (hq ADR 0198) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mesh-nodered container goes with its Dockerfile, build bases and bus credential. The mqtt step runs node on the bundle and reads the binding and settings files where the mesh writes them, from an env-file the mesh fills because a process's env is not given ${port:…}. --- modules/nodered/Dockerfile | 27 ------------ modules/nodered/module.json | 86 +++++++++++++------------------------ 2 files changed, 31 insertions(+), 82 deletions(-) delete mode 100644 modules/nodered/Dockerfile diff --git a/modules/nodered/Dockerfile b/modules/nodered/Dockerfile deleted file mode 100644 index 3031ce6..0000000 --- a/modules/nodered/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -# nodered's runtime: the tool runtime, carrying this module's compiled code. -# -# **Built from this module's own directory and nothing else.** The sdk and the tool runtime are in -# the base images, published like any other artifact — which is what makes this buildable by the -# mesh from a repository and a path (novox/hq ADR 0069) rather than only on a workstation that -# happens to have the siblings. -# -# Two bases, named rather than pinned (novox/hq issue 044): the image this is COMPILED in and the -# image it RUNS in — the second must not carry a compiler. Declared in module.json's `build.on`. -ARG BUILD_BASE -ARG RUNTIME_BASE - -FROM ${BUILD_BASE} AS build -WORKDIR /app/modules/nodered -COPY . . -RUN node /app/node_modules/typescript/bin/tsc client.ts tools/index.ts mqtt/probe.ts mqtt/connection.ts mqtt/index.ts \ - --module NodeNext --moduleResolution NodeNext --target ES2022 --outDir dist - -FROM ${RUNTIME_BASE} -COPY --from=build /app/modules/nodered/dist /app/modules/nodered/dist -# Every serve-time entrypoint, loaded by the runtime in serve mode: tools and events serve, and a -# provider's provisioner runs its reconcile loop in the same process, with the broker connected — -# the convention novox/hq issues 060/061 settled. -ENV MESH_TOOL_MODULES=/app/modules/nodered/dist/tools/index.js -# NOT dist/mqtt/index.js: that is a step the host runs to completion, named by the `mqtt` -# container's args as `mesh-tools run …` (novox/hq ADR 0052). Listed here it would run inside the -# serving sidecar too, and exit it. diff --git a/modules/nodered/module.json b/modules/nodered/module.json index 0ce746a..131de90 100644 --- a/modules/nodered/module.json +++ b/modules/nodered/module.json @@ -12,8 +12,7 @@ "api-token": { "path": "${dir:mesh-state}/api-token", "taken": "at-start" - }, - "broker": "${dir:mesh-state}/broker" + } }, "capabilities": [ "container-runtime" @@ -101,53 +100,31 @@ "content": "{\n \"token\": \"${secret:api-token}\"\n}\n" }, { - "id": "runtime", - "type": "container", - "name": "mesh-nodered", - "network": "host", - "volumes": [ - "${dir:mesh-state}/broker:/run/secrets/broker:ro", - "${dir:mesh-state}/config.json:/run/config/config.json:ro" - ], - "env": { - "MESH_BROKER_FILE": "/run/secrets/broker", - "MESH_NODERED_URL": "http://127.0.0.1:${port:1880}", - "MESH_NODERED_CONFIG_FILE": "/run/config/config.json" - }, - "restart-on": [ - "runtime-config" - ], - "artifact": "runtime" + "id": "mqtt-env", + "type": "file", + "path": "${dir:state}/mqtt.env", + "mode": "0600", + "content": "MESH_NODERED_URL=http://127.0.0.1:${port:1880}\nMESH_NODERED_CONFIG_FILE=${dir:mesh-state}/config.json\nMESH_PROVISIONS_DIR=${dir:state}\nMESH_WRITTEN_DIR=${dir:written}\n" }, { "id": "mqtt", - "type": "container", - "name": "mesh-nodered-mqtt", - "network": "host", - "run-once": true, - "volumes": [ - "${dir:mesh-state}/config.json:/run/config/config.json:ro", - "${dir:written}:/var/lib/nodered-provisions", - "${dir:state}/mqtt-topic.json:/run/provisions/mqtt-topic.json:ro", - "${dir:state}/mqtt-topic.secret:/run/provisions/mqtt-topic.secret:ro", - "${dir:state}/settings.json:/run/provisions/settings.json:ro" + "type": "process", + "name": "nodered-mqtt", + "artifact": "code", + "run": [ + "node", + "mqtt/index.js" ], - "env": { - "MESH_NODERED_URL": "http://127.0.0.1:${port:1880}", - "MESH_NODERED_CONFIG_FILE": "/run/config/config.json", - "MESH_PROVISIONS_DIR": "/run/provisions", - "MESH_WRITTEN_DIR": "/var/lib/nodered-provisions" - }, - "args": [ - "run", - "/app/modules/nodered/dist/mqtt/index.js" + "run-once": true, + "env-file": [ + "${dir:state}/mqtt.env" ], "restart-on": [ + "mqtt-env", "bound-mqtt-topic", "secret-mqtt-topic", "settings" - ], - "artifact": "runtime" + ] } ], "requires": [ @@ -173,23 +150,22 @@ "mqtt-topic": "${dir:state}/mqtt-topic.secret" }, "build": { - "on": [ - { - "arg": "BUILD_BASE", - "module": "mesh-tools", - "artifact": "build" - }, - { - "arg": "RUNTIME_BASE", - "module": "mesh-tools", - "artifact": "runtime" - } - ], "artifacts": [ { - "name": "runtime", - "kind": "image", - "from": "Dockerfile" + "name": "code", + "kind": "bundle", + "language": "typescript", + "entrypoints": [ + "tools/index.js", + "mqtt/index.js" + ], + "loads": [ + "tools/index.js" + ], + "env": { + "MESH_NODERED_URL": "http://127.0.0.1:${port:1880}", + "MESH_NODERED_CONFIG_FILE": "${dir:mesh-state}/config.json" + } } ] }