How to set up MQTT communication channels using NodeRed?

Anni HuangAnni Huang
5 min read

What is MQTT? What are its benefits over HTTP?

MQTT (Message Queuing Telemetry Transport) is a lightweight, publish-subscribe messaging protocol designed for low-bandwidth, high-latency, or unreliable networks. Originally developed by IBM in 1999 for connecting oil pipeline sensors via satellite links. MQTT excels in scenarios requiring efficient, real-time, many-to-many communication, especially in resource-constrained environments, while HTTP remains ideal for traditional web services and APIs.

How to set up NodeRed?

Prerequisites

  • Node.js (version 18.x or higher recommended)
  • npm (comes with Node.js)

Installation Methods

# Install Node-RED globally
npm install -g --unsafe-perm node-red
# Start Node-RED
node-red

Method 2: Local Installation

# Create project directory
mkdir my-node-red-project
cd my-node-red-project
# Initialize npm project
npm init -y
# Install Node-RED locally
npm install node-red
# Install some common dependencies
npm install node-red-node-ui-table
## Dashboard for UI
npm install node-red-dashboard
# MQTT support
npm install node-red-contrib-mqtt-broker

# Database connectivity
npm install node-red-node-sqlite
npm install node-red-node-mysql

# HTTP requests
npm install node-red-contrib-http-request

# File operations
npm install node-red-contrib-fs-ops

# Start Node-RED
npx node-red

Method 3: Docker Installation

# Pull and run Node-RED container
docker run -it -p 1880:1880 --name mynodered nodered/node-red

# For persistent data
docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red

Run it for the first time

1. Access the Editor

  • Open browser and go to http://localhost:1880
  • You'll see the Node-RED flow editor interface

2. Basic Configuration

Node-RED creates a .node-red directory in your home folder containing:

  • settings.js - Main configuration file
  • flows.json - Your flows/programs
  • package.json - Installed nodes

3. Secure Your Installation (Production)

Edit ~/.node-red/settings.js:

module.exports = {
    // Enable authentication
    adminAuth: {
        type: "credentials",
        users: [{
            username: "admin",
            password: "$2b$08$...", // Use node-red-admin to generate
            permissions: "*"
        }]
    },

    // Enable HTTPS
    https: {
        key: require("fs").readFileSync('privatekey.pem'),
        cert: require("fs").readFileSync('certificate.pem')
    },

    // Set custom port
    uiPort: process.env.PORT || 1880,

    // Configure storage
    storageModule: require("node-red-node-sqlite"),
}

Installing Additional Nodes

Via Web Interface (Palette Manager)

  1. Click hamburger menu (☰) → Manage palette
  2. Go to "Install" tab
  3. Search for nodes (e.g., "node-red-dashboard")
  4. Click "Install"

Via Command Line

# Navigate to Node-RED directory
cd ~/.node-red
# Install nodes
npm install node-red-dashboard
npm install node-red-contrib-mqtt-broker
npm install node-red-node-sqlite

Running Node-RED as a Service

Linux (systemd)

Create service file:

sudo nano /etc/systemd/system/node-red.service

Basic Usage

  1. Create Your First Flow
  2. Drag an "inject" node from the palette
  3. Drag a "debug" node
  4. Connect them by dragging from output to input
  5. Double-click nodes to configure
  6. Click "Deploy" to run

  7. Essential Nodes

  8. Input: inject, mqtt in, http in
  9. Output: debug, mqtt out, http response
  10. Function: function, change, switch
  11. Storage: file, database nodes

Example usage

A sample Node-RED flow JSON implementing the Work Order Management module (Function #2). This flow allows you to:

  • Create a work order via HTTP POST
  • Store it in a local database (e.g., using a file node as a simple store or integrate with MongoDB/PostgreSQL)
  • List work orders via HTTP GET
  • Visualize current work orders via a Dashboard Table

Step1. Import the json file

[
  {
    "id": "a1e1e9006a8cf5b2",
    "type": "tab",
    "label": "Work Order Management",
    "disabled": false,
    "info": ""
  },
  {
    "id": "91df9e9c7fd4f90a",
    "type": "http in",
    "z": "a1e1e9006a8cf5b2",
    "name": "Create Work Order",
    "url": "/workorder",
    "method": "post",
    "upload": false,
    "swaggerDoc": "",
    "x": 140,
    "y": 80,
    "wires": [["85078b4647d4d511"]]
  },
  {
    "id": "85078b4647d4d511",
    "type": "function",
    "z": "a1e1e9006a8cf5b2",
    "name": "Add Timestamp & ID",
    "func": "msg.payload.id = Date.now();\nmsg.payload.timestamp = new Date().toISOString();\nreturn msg;",
    "outputs": 1,
    "noerr": 0,
    "initialize": "",
    "finalize": "",
    "libs": [],
    "x": 350,
    "y": 80,
    "wires": [["f878fcf02b6c478e", "25d8e6e3e118dbcf"]]
  },
  {
    "id": "f878fcf02b6c478e",
    "type": "file",
    "z": "a1e1e9006a8cf5b2",
    "name": "Store Work Order",
    "filename": "workorders.json",
    "appendNewline": true,
    "createDir": false,
    "overwriteFile": "false",
    "encoding": "utf8",
    "x": 580,
    "y": 80,
    "wires": [[]]
  },
  {
    "id": "25d8e6e3e118dbcf",
    "type": "http response",
    "z": "a1e1e9006a8cf5b2",
    "name": "",
    "statusCode": "",
    "headers": {},
    "x": 560,
    "y": 140,
    "wires": []
  },
  {
    "id": "257cb2ed5eb9e6aa",
    "type": "http in",
    "z": "a1e1e9006a8cf5b2",
    "name": "List Work Orders",
    "url": "/workorders",
    "method": "get",
    "upload": false,
    "swaggerDoc": "",
    "x": 140,
    "y": 200,
    "wires": [["6211ecf2b8f6fa09"]]
  },
  {
    "id": "6211ecf2b8f6fa09",
    "type": "file in",
    "z": "a1e1e9006a8cf5b2",
    "name": "Read Work Orders",
    "filename": "workorders.json",
    "format": "lines",
    "chunk": false,
    "sendError": true,
    "encoding": "utf8",
    "x": 350,
    "y": 200,
    "wires": [["eb780c0a48bb1b40"]]
  },
  {
    "id": "eb780c0a48bb1b40",
    "type": "function",
    "z": "a1e1e9006a8cf5b2",
    "name": "Parse Lines",
    "func": "let orders = msg.payload.split('\\n').filter(Boolean).map(JSON.parse);\nmsg.payload = orders;\nreturn msg;",
    "outputs": 1,
    "noerr": 0,
    "initialize": "",
    "finalize": "",
    "x": 560,
    "y": 200,
    "wires": [["29b0fc45084c602f", "2e91b8f625d0d122"]]
  },
  {
    "id": "29b0fc45084c602f",
    "type": "http response",
    "z": "a1e1e9006a8cf5b2",
    "name": "",
    "statusCode": "",
    "headers": {},
    "x": 750,
    "y": 160,
    "wires": []
  },
  {
    "id": "2e91b8f625d0d122",
    "type": "ui_table",
    "z": "a1e1e9006a8cf5b2",
    "group": "cf726e81cc73321f",
    "name": "Work Orders Table",
    "order": 1,
    "width": 0,
    "height": 8,
    "columns": [],
    "outputs": 0,
    "cts": true,
    "x": 760,
    "y": 240,
    "wires": []
  },
  {
    "id": "cf726e81cc73321f",
    "type": "ui_group",
    "name": "Work Orders",
    "tab": "aa1592be1219922c",
    "order": 1,
    "disp": true,
    "width": "12",
    "collapse": false
  },
  {
    "id": "aa1592be1219922c",
    "type": "ui_tab",
    "name": "MES Dashboard",
    "icon": "dashboard",
    "order": 1,
    "disabled": false,
    "hidden": false
  }
]

Step 2. Deploy and test it

  1. Create Work Order (POST) Send a JSON POST to http://:1880/workorder with this body:

    {
    "product": "Widget A",
    "qty": 100,
    "line": "Line 1",
    "operator": "John Doe"
    }
    
  2. View All Work Orders (GET) Open http://<your-node-red>:1880/workorders or check the Node-RED dashboard (/ui) for a table.

0
Subscribe to my newsletter

Read articles from Anni Huang directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Anni Huang
Anni Huang

I’m Anni Huang, an AI researcher-in-training currently at ByteDance, specializing in LLM training operations with a coding focus. I bridge the gap between engineering execution and model performance, ensuring the quality, reliability, and timely delivery of large-scale training projects.