Streaming & Messaging Azure

Mosquitto + Node-RED on Ubuntu 24.04 on Azure User Guide

| Product: Mosquitto + Node-RED IoT Stack on Ubuntu 24.04 LTS on Azure

Overview

This image pairs Eclipse Mosquitto, the lightweight open source MQTT message broker, with Node-RED, the flow based low code programming tool, on a single Ubuntu 24.04 LTS VM. It is the canonical IoT starter stack: devices publish telemetry to Mosquitto, and Node-RED subscribes, transforms and routes those messages visually.

The integration is pre wired and proven at every boot. Node-RED's broker connection already points at the local Mosquitto with this VM's own generated credentials, a demo flow round trips a real message through the broker on first boot, and both the broker password and the editor admin password are unique to your VM.

What is included:

  • Eclipse Mosquitto 2.0.18 MQTT broker on port 1883, authentication required (anonymous access disabled)
  • Node-RED 5.0.4 on Node.js 22 LTS, run as a dedicated systemd service bound to loopback
  • nginx on port 80 fronting the flow editor (websocket proxied), with an unauthenticated /health endpoint for probes
  • A demo flow, already deployed: an inject node publishes to topic cloudimg/demo through the real broker, and a subscriber node receives it, shows it in the debug sidebar and appends it to a log file
  • Per VM credentials generated on first boot: the broker user cloudimg and the editor user admin, both written to a root only file
  • Licence texts for both components shipped in the image under /usr/share/cloudimg/licenses/mosquitto-node-red/
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is comfortable for this stack; scale up for very high message rates or heavy flows. NSG inbound: allow 22/tcp from your management network, 80/tcp for the flow editor, and 1883/tcp for MQTT devices (restrict the source ranges to your device networks).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Mosquitto Node-RED by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Then Review + create -> Create. After the VM deploys, open port 1883 for your MQTT devices (Step 2 shows the CLI form).

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name mosquitto-node-red \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

az vm open-port --resource-group <your-rg> --name mosquitto-node-red --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name mosquitto-node-red --port 1883 --priority 1020

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

systemctl is-active mosquitto node-red nginx

All three report active:

active
active
active

Services active and component versions

Step 5 - Retrieve your credentials

Both passwords are generated uniquely on the first boot of your VM and written to a root only file:

sudo cat /root/mosquitto-node-red-credentials.txt

The file contains the broker credentials (MOSQUITTO_USER / MOSQUITTO_PASSWORD, broker user cloudimg) and the flow editor credentials (NODE_RED_ADMIN_USER / NODE_RED_ADMIN_PASSWORD, editor user admin), plus ready to copy connection examples. Store both passwords somewhere safe.

Step 6 - Check the health endpoint

nginx serves an unauthenticated health endpoint for load balancers and probes:

curl -s http://localhost/health

It returns ok.

Step 7 - Publish and subscribe through the broker

The broker requires authentication; anonymous connections are rejected. Read the generated password into a variable, then round trip a message:

MQPASS=$(sudo grep '^MOSQUITTO_PASSWORD=' /root/mosquitto-node-red-credentials.txt | cut -d= -f2-)
mosquitto_sub -h localhost -u cloudimg -P "$MQPASS" -t 'demo/greeting' -C 1 -W 10 &
sleep 1
mosquitto_pub -h localhost -u cloudimg -P "$MQPASS" -t 'demo/greeting' -m "hello from the shell"
wait

The subscriber prints the published message:

hello from the shell

Anonymous access is off. An unauthenticated client is refused:

$ mosquitto_pub -h localhost -t test -m x
Connection error: Connection Refused: not authorised.

Authenticated broker round trip and anonymous rejection

Step 8 - Open the flow editor

Browse to http://<vm-public-ip>/ and sign in as admin with the NODE_RED_ADMIN_PASSWORD from Step 5.

Node-RED login page

The editor opens on the MQTT Demo flow that ships with the image. Both MQTT nodes show a green connected badge: Node-RED is already authenticated against the local Mosquitto with this VM's generated credentials, with no configuration needed.

The pre wired MQTT demo flow with both broker nodes connected

Click the button on the Send test message inject node to publish a message to cloudimg/demo through the real broker; the subscribe cloudimg/demo node receives it and shows it in the debug sidebar.

Step 9 - Watch an MQTT message arrive in Node-RED

Prove the end to end chain from the shell. The demo flow appends every message it receives on cloudimg/demo to /var/lib/node-red/mqtt-inbox.log:

MQPASS=$(sudo grep '^MOSQUITTO_PASSWORD=' /root/mosquitto-node-red-credentials.txt | cut -d= -f2-)
mosquitto_pub -h localhost -u cloudimg -P "$MQPASS" -t cloudimg/demo -m "sensor reading 21.5"
sleep 2
sudo tail -n 1 /var/lib/node-red/mqtt-inbox.log

The last line of the log is the message you just published:

sensor reading 21.5

The same message appears live in the editor's debug sidebar:

The debug sidebar showing MQTT messages received through the broker

Publishing a message and reading it back from the flow's log file

Step 10 - Connect devices and external clients

With port 1883 open in your NSG, any MQTT client can connect using the broker credentials from Step 5:

# From a device or workstation:
mosquitto_pub -h <vm-public-ip> -u cloudimg -P '<MOSQUITTO_PASSWORD>' -t sensors/temperature -m '21.5'
mosquitto_sub -h <vm-public-ip> -u cloudimg -P '<MOSQUITTO_PASSWORD>' -t 'sensors/#' -v

To route a new topic into Node-RED, add an mqtt in node in the editor, select the existing Local Mosquitto broker configuration, set your topic (for example sensors/#) and click Deploy.

To add more broker users, use mosquitto_passwd (without -c, which would recreate the file) and reload:

sudo mosquitto_passwd -b /etc/mosquitto/passwd sensor01 '<new-password>'
sudo systemctl reload mosquitto

Step 11 - Confirm the runtime from the command line

The Node-RED admin API is protected by the same editor login. Obtain a bearer token and query the runtime settings:

NRPASS=$(sudo grep '^NODE_RED_ADMIN_PASSWORD=' /root/mosquitto-node-red-credentials.txt | cut -d= -f2-)
TOKEN=$(curl -s --data "client_id=node-red-admin&grant_type=password&scope=*&username=admin&password=${NRPASS}" http://localhost/auth/token | jq -r .access_token)
curl -s -H "Authorization: Bearer ${TOKEN}" http://localhost/settings | jq '{version, httpNodeRoot}'
{
  "version": "5.0.4",
  "httpNodeRoot": "/api/"
}

Health endpoint and authenticated admin API

Step 12 - Install extra palette nodes

Node-RED has a catalogue of thousands of community nodes for databases, dashboards, cloud services and protocols. Install them from the editor via Menu -> Manage palette -> Install.

The palette manager showing installed nodes and the Install tab

After installing nodes from the command line instead (sudo -u node-red npm --prefix /var/lib/node-red install <node>), restart Node-RED so it loads them:

sudo systemctl restart node-red

Server Components

Component Version Detail
Eclipse Mosquitto 2.0.18 MQTT broker on 0.0.0.0:1883, allow_anonymous false, password file auth
Node-RED 5.0.4 Flow editor + runtime on loopback 127.0.0.1:1880, adminAuth enabled
Node.js 22 LTS Runtime for Node-RED (NodeSource)
nginx 1.24 Reverse proxy :80 -> Node-RED, websocket aware, /health endpoint
Ubuntu 24.04 LTS Fully patched at image capture; unattended upgrades enabled

Key Paths

Path Purpose
/root/mosquitto-node-red-credentials.txt Per VM credentials (root only, generated at first boot)
/etc/mosquitto/conf.d/cloudimg.conf Broker listener + authentication configuration
/etc/mosquitto/passwd Broker password file (mosquitto_passwd format)
/var/lib/mosquitto/ Broker persistence store
/var/lib/node-red/ Node-RED user directory: flows.json, credential store, settings, installed nodes
/var/lib/node-red/mqtt-inbox.log File sink written by the demo flow
/usr/share/cloudimg/licenses/mosquitto-node-red/ Licence texts: Node-RED Apache 2.0; Mosquitto EPL 2.0 / EDL 1.0 (distributed under the EDL 1.0 arm)

Managing the services

systemctl status mosquitto --no-pager -l | head -n 5
● mosquitto.service - Mosquitto MQTT Broker
     Loaded: loaded (/usr/lib/systemd/system/mosquitto.service; enabled; preset: enabled)
     Active: active (running)

Restart either component after configuration changes:

sudo systemctl restart mosquitto
sudo systemctl restart node-red
sudo systemctl reload nginx

Enabling HTTPS

nginx terminates plain HTTP on port 80. For public exposure of the editor, add a DNS name for the VM and extend the nginx site with a TLS server block (for example with certbot), or front the VM with an Azure Application Gateway. Keep Node-RED itself bound to loopback so the only public editor surface is the authenticated, TLS terminated proxy. For MQTT over TLS, add a listener 8883 block with certificate paths to /etc/mosquitto/conf.d/cloudimg.conf and open 8883 instead of 1883.

Troubleshooting

The editor rejects your password. Re read NODE_RED_ADMIN_PASSWORD from the credentials file; it is unique to this VM. If you have rotated it, restart Node-RED after editing /var/lib/node-red/settings.js.

MQTT clients cannot connect from outside. Confirm port 1883 is open in the NSG and that your client passes -u cloudimg -P '<password>'. The broker logs to the journal: sudo journalctl -u mosquitto -n 20.

The demo flow shows no messages. Check the broker connection badges in the editor. Both MQTT nodes should read connected; the runtime journal (sudo journalctl -u node-red -n 20) shows the connection log line Connected to broker: node-red-cloudimg@mqtt://127.0.0.1:1883.

First boot state. The one shot mosquitto-node-red-firstboot.service generates all credentials before the runtime starts. Its log is in the journal: sudo journalctl -u mosquitto-node-red-firstboot -n 30.

Security Recommendations

  • Restrict NSG source ranges for ports 80 and 1883 to your own networks; do not leave them open to the internet.
  • Add TLS (see Enabling HTTPS) before exposing the editor or the broker publicly.
  • Create dedicated broker users per device with mosquitto_passwd instead of sharing the cloudimg account.
  • Rotate the editor and broker passwords periodically; the credentials file documents both.
  • The OS keeps patching itself via unattended upgrades; reboot when /var/run/reboot-required appears.

Support

cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.