Node-RED on Kubernetes & OpenClaw on Ubuntu 24.04 — Integration Guide
Table of Contents
- Part 1: Installing Node-RED on Kubernetes
- Part 2: Installing OpenClaw on Ubuntu 24.04 LTS
- Part 3: Integrating Node-RED with OpenClaw
Part 1: Installing Node-RED on Kubernetes
Prerequisites
- A running Kubernetes cluster (k3s, OpenShift, EKS, GKE, AKS, etc.)
kubectlconfigured and connected to your cluster- A default StorageClass available for PersistentVolumeClaims
1.1 Create a Namespace
kubectl create namespace node-red
1.2 Create a PersistentVolumeClaim
Node-RED needs persistent storage for flows, credentials, and settings.
# nodered-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nodered-data
namespace: node-red
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
kubectl apply -f nodered-pvc.yaml
1.3 Create the Deployment
# nodered-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: node-red
namespace: node-red
labels:
app: node-red
spec:
replicas: 1
selector:
matchLabels:
app: node-red
template:
metadata:
labels:
app: node-red
spec:
securityContext:
runAsUser: 1000
fsGroup: 1000
containers:
- name: node-red
image: nodered/node-red:latest
ports:
- containerPort: 1880
name: http
env:
- name: TZ
value: "Europe/London"
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /
port: 1880
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 1880
initialDelaySeconds: 10
periodSeconds: 5
volumes:
- name: data
persistentVolumeClaim:
claimName: nodered-data
kubectl apply -f nodered-deployment.yaml
1.4 Create the Service
# nodered-service.yaml
apiVersion: v1
kind: Service
metadata:
name: node-red
namespace: node-red
spec:
selector:
app: node-red
ports:
- name: http
port: 1880
targetPort: 1880
type: ClusterIP
kubectl apply -f nodered-service.yaml
Note: If you need external access, changetype: ClusterIPtotype: LoadBalancer, or configure an Ingress resource (see section 1.5).
1.5 Optional: Ingress
If you have an Ingress controller installed (e.g. nginx-ingress):
# nodered-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: node-red
namespace: node-red
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: nodered.yourdomain.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: node-red
port:
number: 1880
kubectl apply -f nodered-ingress.yaml
1.6 Quick Access via Port-Forward
For immediate access without Ingress:
kubectl port-forward svc/node-red 1880:1880 -n node-red
Then open http://localhost:1880 in your browser.
1.7 Verify the Deployment
kubectl get all -n node-red
kubectl logs -l app=node-red -n node-red
1.8 Securing Node-RED (Recommended)
Node-RED ships with no authentication by default. To add a password, create a settings.js ConfigMap and mount it into /data/settings.js.
Generate a bcrypt hash for your password first:
npx -p node-red node -e "console.log(require('bcryptjs').hashSync('YourPassword', 8))"
Then create a ConfigMap with your settings and mount it — refer to the Node-RED security docs for the full adminAuth config block.
1.9 OpenShift-Specific Notes
If deploying on OpenShift, you will need an SCC allowance for the UID:
oc adm policy add-scc-to-user nonroot -z default -n node-red
Or use anyuid if nonroot is insufficient for the image:
oc adm policy add-scc-to-user anyuid -z default -n node-red
Part 2: Installing OpenClaw on Ubuntu 24.04 LTS
OpenClaw is an AI agent gateway. This section covers installation on a bare Ubuntu 24.04 host and configuring it as a persistent systemd service.
Prerequisites
- Ubuntu 24.04 LTS
- Root or sudo access
- Outbound internet access to reach your AI model provider (Anthropic, OpenAI, Gemini, etc.)
- At least one API key for a model provider
2.1 Install Node.js 24
OpenClaw requires Node 22.14+ (Node 24 recommended). The installer script handles this automatically, but you can pre-install it:
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v # should report v24.x.x
2.2 Install OpenClaw
The recommended approach is the official installer script, which detects your OS, installs Node if needed, installs OpenClaw, and launches onboarding:
curl -fsSL https://openclaw.ai/install.sh | bash
To install without running the interactive onboarding (useful for servers):
curl -fsSL https://openclaw.ai/install.sh | bash -s -- --no-onboard
Verify the install:
openclaw --version
openclaw doctor
2.3 Alternative: npm Install
If you manage Node yourself:
npm install -g openclaw@latest
openclaw onboard --install-daemon
If openclaw is not found after install, add the npm global bin directory to your PATH:
echo 'export PATH="$(npm prefix -g)/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
2.4 Set Your Model Provider API Key
Export your API key before starting the gateway. Replace ANTHROPIC with your provider (OPENAI, GEMINI, OPENROUTER):
export ANTHROPIC_API_KEY="sk-ant-..."
To make this permanent, add it to your shell profile or use the systemd environment approach below.
2.5 Start the Gateway
openclaw gateway --port 18789
Check it is healthy:
openclaw gateway status
openclaw status
openclaw logs --follow
A healthy baseline shows Runtime: running and RPC probe: ok.
2.6 Configure as a systemd Service (Recommended for Servers)
Install the gateway as a systemd user service:
openclaw gateway install
systemctl --user enable --now openclaw-gateway.service
To keep the service running after you log out, enable lingering:
sudo loginctl enable-linger $USER
For a system-wide service (multi-user/always-on):
sudo systemctl daemon-reload
sudo systemctl enable --now openclaw-gateway.service
Tune the service for a server environment:
sudo systemctl edit openclaw-gateway
Add the following override:
[Service]
Environment=OPENCLAW_NO_RESPAWN=1
Environment=NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache
Environment=ANTHROPIC_API_KEY=sk-ant-YOUR_KEY_HERE
Restart=always
RestartSec=2
TimeoutStartSec=90
Reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart openclaw-gateway
2.7 Startup Tuning (Optional)
For faster repeated startup times, enable Node's module compile cache:
grep -q 'NODE_COMPILE_CACHE' ~/.bashrc || cat >> ~/.bashrc <<'EOF'
export NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache
mkdir -p /var/tmp/openclaw-compile-cache
export OPENCLAW_NO_RESPAWN=1
EOF
source ~/.bashrc
2.8 Verify the Install
openclaw gateway status
openclaw channels status --probe
openclaw health
Access the Control UI at http://localhost:18789 (gateway binds to loopback by default).
2.9 Remote Access via SSH Tunnel
The gateway binds to loopback by default. To access it from another machine securely:
ssh -N -L 18789:127.0.0.1:18789 user@your-ubuntu-host
Then connect your browser to http://127.0.0.1:18789.
For persistent remote access, Tailscale Serve is the recommended approach — see the OpenClaw Tailscale docs.
Part 3: Integrating Node-RED with OpenClaw
OpenClaw exposes an OpenAI-compatible HTTP API on its gateway port (18789 by default). Node-RED integrates with it via standard HTTP request nodes — no special plugin required.
3.1 Architecture Overview
[Node-RED Flow]
|
| HTTP POST (JSON)
v
[OpenClaw Gateway :18789]
|
| Routes to provider
v
[AI Model (Anthropic / OpenAI / etc.)]
|
v
[Response back to Node-RED]
Node-RED sends a prompt to OpenClaw's OpenAI-compatible /v1/chat/completions endpoint. OpenClaw handles routing to whichever model provider you have configured.
3.2 Get Your Gateway Token
The gateway requires an auth token. Retrieve it:
# If running locally on Ubuntu:
openclaw gateway status --json | jq '.auth'
# Or check your openclaw.json config:
cat ~/.openclaw/openclaw.json | grep token
If you set OPENCLAW_GATEWAY_TOKEN as an environment variable, use that value.
3.3 Node-RED: Basic Prompt Flow
This flow takes a message payload, sends it to OpenClaw, and returns the AI response.
In Node-RED, create the following flow:
[inject] → [function: build request] → [http request] → [function: parse response] → [debug]
Function node: "Build Request"
// Set your OpenClaw gateway URL and token
const OPENCLAW_URL = "http://<openclaw-host>:18789/v1/chat/completions";
const OPENCLAW_TOKEN = "<your-gateway-token>";
msg.url = OPENCLAW_URL;
msg.method = "POST";
msg.headers = {
"Content-Type": "application/json",
"Authorization": "Bearer " + OPENCLAW_TOKEN
};
msg.payload = {
model: "claude-sonnet-4-20250514", // or whichever model you have configured
messages: [
{
role: "user",
content: msg.payload // expects a string input from upstream
}
],
max_tokens: 1000
};
return msg;
HTTP Request node settings:
- Method:
POST - URL: leave blank (set by function node via
msg.url) - Return:
a parsed JSON object - Enable "Use msg.url" and "Use msg.headers"
Function node: "Parse Response"
// Extract the assistant's reply from the OpenAI-compatible response
if (msg.payload && msg.payload.choices && msg.payload.choices.length > 0) {
msg.payload = msg.payload.choices[0].message.content;
} else {
msg.payload = "Error: no response from OpenClaw";
}
return msg;
3.4 Node-RED: Reusable OpenClaw Subflow
For production use, create a subflow so any flow in your workspace can call OpenClaw without duplicating config.
Create a subflow with:
- Input:
msg.prompt(string) - Output:
msg.response(string)
Subflow function node:
const OPENCLAW_URL = env.get("OPENCLAW_URL") || "http://localhost:18789/v1/chat/completions";
const OPENCLAW_TOKEN = env.get("OPENCLAW_TOKEN");
msg.url = OPENCLAW_URL;
msg.method = "POST";
msg.headers = {
"Content-Type": "application/json",
"Authorization": "Bearer " + OPENCLAW_TOKEN
};
msg.payload = {
model: env.get("OPENCLAW_MODEL") || "claude-sonnet-4-20250514",
messages: [{ role: "user", content: msg.prompt }],
max_tokens: parseInt(env.get("OPENCLAW_MAX_TOKENS") || "1000")
};
return msg;
Set the environment variables in the subflow's properties panel:
| Variable | Example Value |
|---|---|
OPENCLAW_URL |
http://192.168.1.x:18789/v1/chat/completions |
OPENCLAW_TOKEN |
your-gateway-token |
OPENCLAW_MODEL |
claude-sonnet-4-20250514 |
OPENCLAW_MAX_TOKENS |
1000 |
3.5 Connecting Node-RED (in Kubernetes) to OpenClaw (on Ubuntu)
When Node-RED runs in Kubernetes and OpenClaw runs on a separate Ubuntu host, you have a few connectivity options:
Option A — Direct IP (simplest)
Use the Ubuntu host's LAN IP in Node-RED's HTTP request node:
http://192.168.1.x:18789/v1/chat/completions
Note: the OpenClaw gateway binds to loopback by default. You need to change the bind mode to allow external connections. Edit ~/.openclaw/openclaw.json:
{
"gateway": {
"bind": "lan",
"auth": {
"token": "your-strong-token-here"
}
}
}
Then restart the gateway:
openclaw gateway restart
Option B — Tailscale (recommended for security)
If both your K8s nodes and Ubuntu host are on Tailscale, use the Tailscale IP:
http://100.x.x.x:18789/v1/chat/completions
Set the bind to tailnet in openclaw.json and keep auth enabled. This keeps the gateway off your LAN entirely.
Option C — Kubernetes ExternalName Service
For a clean in-cluster DNS approach, create an ExternalName service in the node-red namespace pointing at your Ubuntu host:
# openclaw-external-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: openclaw
namespace: node-red
spec:
type: ExternalName
externalName: your-ubuntu-host.home # or IP
ports:
- port: 18789
kubectl apply -f openclaw-external-svc.yaml
Node-RED can then reference OpenClaw via the in-cluster DNS name http://openclaw.node-red.svc.cluster.local:18789.
3.6 Storing the Gateway Token Securely in Kubernetes
Rather than hardcoding the token in your Node-RED flows, store it as a Kubernetes Secret and mount it as an environment variable:
kubectl create secret generic openclaw-token \
--from-literal=OPENCLAW_TOKEN=your-gateway-token \
-n node-red
Add to your Node-RED deployment spec under spec.template.spec.containers[0].env:
- name: OPENCLAW_TOKEN
valueFrom:
secretKeyRef:
name: openclaw-token
key: OPENCLAW_TOKEN
Then reference it in your Node-RED function nodes via env.get("OPENCLAW_TOKEN") (using the subflow approach from section 3.4).
3.7 Testing End-to-End
- Deploy Node-RED and verify it is accessible at
http://localhost:1880 - Verify OpenClaw is healthy:
openclaw gateway status - In Node-RED, inject a test string (e.g.
"Hello, what is 2+2?") into your flow - Check the debug panel for the AI response
- Check OpenClaw logs for the request:
openclaw logs --follow
3.8 Example Use Cases
- Automated summaries: Feed MQTT sensor data into Node-RED → OpenClaw → summarise and push to a dashboard or Slack channel
- Natural language commands: Translate plain-English instructions from a UI into structured actions via OpenClaw, then execute them with Node-RED automation nodes
- Alert enrichment: Receive a webhook alert, send it to OpenClaw for analysis and suggested remediation, then route the enriched alert to your ticketing system
- Scheduled AI reports: Trigger a cron-style inject node on a schedule, gather data, pass to OpenClaw for a written summary, and email or post it
Troubleshooting Reference
| Symptom | Likely Cause | Fix |
|---|---|---|
Node-RED pod CrashLoopBackOff |
PVC not bound / permissions | Check StorageClass; add SCC on OpenShift |
ECONNREFUSED from Node-RED to OpenClaw |
Gateway bound to loopback | Change gateway.bind to lan or tailnet |
unauthorized from OpenClaw |
Token mismatch | Check OPENCLAW_TOKEN env var matches openclaw.json |
openclaw not found after install |
npm global bin not in PATH | export PATH="$(npm prefix -g)/bin:$PATH" |
| Gateway won't bind non-loopback without auth | Security guard | Set gateway.auth.token before changing bind mode |
| Node-RED flows lost after pod restart | PVC not mounted | Verify PVC is bound and mounted to /data |