Demo Environment Setup Guide
Demo Environment Setup Guide
Overview
Section titled “Overview”This section provides a step-by-step guide to set up a complete IoT demonstration environment. By the end of this section, you will be able to:
- Deploy the entire IoT backend stack in under 10 minutes using Docker Compose
- Verify each component is working correctly
- Perform basic MQTT publish-subscribe tests
- Access Node-RED, InfluxDB, and Grafana interfaces
- Prepare the environment for customer demonstrations
Prerequisites
Section titled “Prerequisites”Before starting, ensure the following are available:
- Docker (version 24.0 or newer): Install Docker
- Docker Compose (version 2.20 or newer): Included with Docker Desktop, or install separately on Linux
- A computer with at least 4 GB RAM and 10 GB free disk space
- Internet connection for pulling container images (first-time setup: ~1 GB download)
- ESP32 board (optional for initial testing, MQTT client tools can simulate devices)
Verify Docker Installation
Section titled “Verify Docker Installation”Open a terminal and run:
docker --versiondocker compose versionExpected output (versions may vary):
Docker version 27.0.0, build abcdef1Docker Compose version v2.29.0If Docker is not installed, download Docker Desktop from docker.com and follow the installation wizard.
Step 1: Create the Project Directory
Section titled “Step 1: Create the Project Directory”Create a directory for the demo environment:
mkdir ~/iot-democd ~/iot-demoStep 2: Create Docker Compose Configuration
Section titled “Step 2: Create Docker Compose Configuration”Create a file named docker-compose.yml in the ~/iot-demo directory:
version: "3.8"
services: # MQTT Broker mosquitto: image: eclipse-mosquitto:2 container_name: mosquitto ports: - "1883:1883" - "8883:8883" volumes: -./mosquitto/config:/mosquitto/config -./mosquitto/data:/mosquitto/data -./mosquitto/log:/mosquitto/log restart: unless-stopped
# Node-RED Automation Engine nodered: image: nodered/node-red:4 container_name: nodered ports: - "1880:1880" volumes: -./nodered/data:/data environment: - TZ=UTC restart: unless-stopped depends_on: - mosquitto
# InfluxDB Time-Series Database influxdb: image: influxdb:2 container_name: influxdb ports: - "8086:8086" volumes: -./influxdb/data:/var/lib/influxdb2 -./influxdb/config:/etc/influxdb2 environment: - DOCKER_INFLUXDB_INIT_MODE=setup - DOCKER_INFLUXDB_INIT_USERNAME=admin - DOCKER_INFLUXDB_INIT_PASSWORD=admin123 - DOCKER_INFLUXDB_INIT_ORG=iot-demo - DOCKER_INFLUXDB_INIT_BUCKET=sensor-data - DOCKER_INFLUXDB_INIT_RETENTION=30d restart: unless-stopped
# Grafana Visualization grafana: image: grafana/grafana:11 container_name: grafana ports: - "3000:3000" volumes: -./grafana/data:/var/lib/grafana -./grafana/config:/etc/grafana environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=admin123 - GF_INSTALL_PLUGINS= restart: unless-stopped depends_on: - influxdbConfiguration notes:
- The MQTT broker is exposed on port 1883 (unencrypted) for local development. For production, use port 8883 with TLS.
- InfluxDB is initialized with a demo organization, bucket, and credentials. These should be changed for production.
- Grafana is pre-configured with admin credentials. Change these for any non-demo use.
- All services use persistent volumes so data survives container restarts.
Step 3: Create Mosquitto Configuration
Section titled “Step 3: Create Mosquitto Configuration”Create the Mosquitto configuration directory and file:
mkdir -p mosquitto/configCreate mosquitto/config/mosquitto.conf:
# Mosquitto Configuration for IoT Demolistener 1883protocol mqtt
# Allow anonymous access for demo purposesallow_anonymous true
# Persistencepersistence truepersistence_location /mosquitto/data/
# Logginglog_dest file /mosquitto/log/mosquitto.loglog_dest stdoutlog_type all
# Maximum connectionsmax_connections 1000Important security note: The configuration above allows anonymous access for demo purposes. In any production or internet-facing deployment, always:
- Set
allow_anonymous false - Configure username/password authentication
- Use TLS encryption (see Section 16 for details)
Create the data directories:
mkdir -p mosquitto/data mosquitto/logStep 4: Start the Stack
Section titled “Step 4: Start the Stack”Start all services:
cd ~/iot-demodocker compose up -dDocker will pull all images (first time only) and start the containers. This typically takes 2-5 minutes depending on internet speed.
Expected output:
[+] Running 5/5 ✔ Container mosquitto Started ✔ Container influxdb Started ✔ Container nodered Started ✔ Container grafana StartedCheck the status of all containers:
docker compose psExpected output:
NAME IMAGE STATUS PORTSmosquitto eclipse-mosquitto:2 Up 2 minutes 0.0.0.0:1883->1883/tcp, 0.0.0.0:8883->8883/tcpnodered nodered/node-red:4 Up 2 minutes 0.0.0.0:1880->1880/tcpinfluxdb influxdb:2 Up 2 minutes 0.0.0.0:8086->8086/tcpgrafana grafana/grafana:11 Up 2 minutes 0.0.0.0:3000->3000/tcpStep 5: Configure InfluxDB
Section titled “Step 5: Configure InfluxDB”InfluxDB is automatically initialized with the credentials specified in docker-compose.yml. To verify:
- Open a browser and navigate to
http://localhost:8086 - Log in with username
adminand passwordadmin123 - You should see the InfluxDB UI showing the
sensor-databucket
If the automatic setup did not complete (first-time initialization can be timing-sensitive), complete it manually:
- Click “Get Started”
- Enter: Username
admin, Passwordadmin123, Organizationiot-demo, Bucketsensor-data - Click “Continue”
Retrieve the API token (needed for Node-RED to write data):
docker exec influxdb influx auth list --org iot-demoCopy the token string (a long hexadecimal value). Save it — you will need it when configuring Node-RED in later sections.
Step 6: Access Node-RED
Section titled “Step 6: Access Node-RED”- Open a browser and navigate to
http://localhost:1880 - You should see the Node-RED flow editor interface
- No authentication is configured by default (in production, enable admin authentication)
Quick verification test:
- Drag an “Inject” node (from the left palette) onto the workspace
- Drag a “Debug” node onto the workspace
- Connect the Inject node output to the Debug node input
- Click the “Deploy” button (top right)
- Click the button on the left side of the Inject node
- Check the Debug sidebar (right panel) — you should see
timestampmessages appearing
Step 7: Access Grafana
Section titled “Step 7: Access Grafana”- Open a browser and navigate to
http://localhost:3000 - Log in with username
adminand passwordadmin123 - Grafana will prompt you to change the password — click “Skip” for demo purposes
Add InfluxDB as a data source:
- Go to Connections → Data Sources → Add data source
- Search for and select “InfluxDB”
- Configure:
- Query Language: Flux
- URL:
http://influxdb:8086(use the Docker service name, not localhost) - Organization:
iot-demo - Token: (paste the token from Step 5)
- Default Bucket:
sensor-data
- Click “Save & Test” — you should see a “Data source is working” confirmation
Step 8: Test MQTT Communication
Section titled “Step 8: Test MQTT Communication”To verify the MQTT broker is working, use MQTT command-line tools or MQTT Explorer.
Using mosquitto_pub/sub (CLI)
Section titled “Using mosquitto_pub/sub (CLI)”Install MQTT clients if not already available:
# macOSbrew install mosquitto
# Ubuntu/Debiansudo apt-get install mosquitto-clientsIn one terminal, subscribe to a test topic:
mosquitto_sub -h localhost -p 1883 -t "demo/test" -vIn another terminal, publish a test message:
mosquitto_pub -h localhost -p 1883 -t "demo/test" -m '{"message":"Hello IoT Demo","timestamp":1712345678}'The subscriber terminal should display:
demo/test {"message":"Hello IoT Demo","timestamp":1712345678}Using MQTT Explorer (GUI)
Section titled “Using MQTT Explorer (GUI)”MQTT Explorer is a free desktop application that provides a visual interface:
- Download and install MQTT Explorer
- Create a new connection:
- Host:
localhost - Port:
1883 - No username/password (anonymous)
- Click “Connect”
- You will see a live view of all topics as data flows through the broker
- You can also publish test messages directly from the interface
Step 9: Simulate Sensor Data (Node-RED)
Section titled “Step 9: Simulate Sensor Data (Node-RED)”To demonstrate the data pipeline without physical hardware, create a simulated sensor flow in Node-RED:
- In Node-RED, create a new flow by clicking ”+” next to the tab name
- Add these nodes:
- Inject node (configured to repeat every 10 seconds)
- Function node (to generate random sensor values)
- MQTT Out node (to publish to the broker)
Configure the Inject node:
- Payload:
timestamp - Repeat:
interval, every10seconds - Name:
Every 10s
Configure the Function node with this JavaScript code:
// Generate random sensor data simulating an ESP32const sensorData = { device_id: "esp32_sim_01", temperature: Math.round((20 + Math.random * 15) * 10) / 10, // 20-35°C humidity: Math.round((40 + Math.random * 40) * 10) / 10, // 40-80% light: Math.round(Math.random * 1000), // 0-1000 lux battery: Math.round((80 + Math.random * 20) * 10) / 10, // 80-100% timestamp: Date.now};
msg.payload = sensorData;msg.topic = "factory/zone1/environment";return msg;Configure the MQTT Out node:
- Server:
localhost:1883(or use the Mosquitto broker node) - Topic:
factory/zone1/environment - QoS:
1 - Name:
Publish Sensor Data
Connect: Inject → Function → MQTT Out
Deploy the flow. You should see data appearing in the MQTT Explorer under the factory/zone1/environment topic.
Step 10: Write Simulated Data to InfluxDB
Section titled “Step 10: Write Simulated Data to InfluxDB”To complete the data pipeline, add InfluxDB storage:
- Install the InfluxDB node palette:
- Click the hamburger menu (top right) → Manage palette
- Go to the “Install” tab
- Search for
node-red-contrib-influxdband install
- Add an InfluxDB Out node to your flow
- Configure the InfluxDB node:
- Server: Create a new InfluxDB server config
- URL:
http://influxdb:8086 - Token: (paste the InfluxDB API token from Step 5)
- Organization:
iot-demo - Bucket:
sensor-data
- Wire: MQTT In → Function → InfluxDB Out
A complete minimal flow now looks like:
Inject (10s) → Function (generate data) → MQTT Out (publish) ↓ MQTT In (subscribe) → InfluxDB Out (store)Verification Checklist
Section titled “Verification Checklist”After completing all steps, verify each component:
- Docker: All 4 containers are running (
docker compose ps) - Mosquitto: MQTT broker accepts connections on port 1883 (
mosquitto_sub test) - Node-RED: Flow editor accessible at
http://localhost:1880 - InfluxDB: Web UI accessible at
http://localhost:8086, bucketsensor-dataexists - Grafana: Login at
http://localhost:3000, InfluxDB data source configured - Data Pipeline: Simulated sensor data flows from Inject → InfluxDB (visible in InfluxDB Data Explorer)
Stopping and Cleaning Up
Section titled “Stopping and Cleaning Up”To stop the demo environment:
cd ~/iot-demodocker compose downTo stop and remove all data (clean slate):
cd ~/iot-demodocker compose down -vrm -rf mosquitto/data mosquitto/log nodered/data influxdb/data grafana/dataTroubleshooting
Section titled “Troubleshooting”Container fails to start
Section titled “Container fails to start”Symptom: docker compose up -d returns exit code for one or more containers.
Check logs:
docker compose logs <service-name>Common cause: Port already in use.
# Check what is using port 1883lsof -i :1883# Stop the conflicting service or change the port mapping in docker-compose.ymlCannot connect to MQTT broker
Section titled “Cannot connect to MQTT broker”Symptom: mosquitto_sub returns “Connection refused”.
Verify the broker is running:
docker compose ps mosquittoCheck Mosquitto logs:
docker compose logs mosquittoTry connecting with verbose output:
mosquitto_sub -h localhost -p 1883 -t "test" -dNode-RED cannot reach InfluxDB
Section titled “Node-RED cannot reach InfluxDB”Symptom: InfluxDB Out node shows “Connection error”.
Ensure both are on the same Docker network — Docker Compose automatically creates a network for all services, so using the service name influxdb (not localhost) in the InfluxDB node configuration resolves this.
Grafana shows “No data” in panels
Section titled “Grafana shows “No data” in panels”Symptom: Dashboard panels display “No data” or “Query error”.
Check:
- Is the InfluxDB data source configured with the correct URL? Use
http://influxdb:8086(notlocalhost). - Is the token correct? (Retrieve with
docker exec influxdb influx auth list) - Are there data points in the bucket? Check in InfluxDB Data Explorer.
- Is the query using the correct bucket name? Default is
sensor-data.
Demo Environment Hardware Kit (Optional)
Section titled “Demo Environment Hardware Kit (Optional)”For a complete demo experience with physical hardware, the following components are recommended:
| Component | Recommended Model | Approx. Cost | Search Term |
|---|---|---|---|
| ESP32 board | ESP32 DevKit V1 | $5-8 | ”ESP32 WiFi Bluetooth Development Board” |
| Temperature sensor | DHT22 | $3-5 | ”DHT22 Temperature Humidity Sensor Module” |
| Light sensor | BH1750 | $2-4 | ”BH1750 Light Intensity Sensor Module GY-302” |
| Relay module | 2-channel 5V relay | $3-6 | ”5V 2-Channel Relay Module Optocoupler” |
| Breadboard + wires | 830-point breadboard | $5-8 | ”Breadboard 830 Points + 65 Jumper Wires” |
| USB cable | USB-A to Micro-USB | $2-4 | ”USB to Micro USB Data Cable for ESP32” |
| Total | $20-35 |
This hardware kit allows you to demonstrate:
- Temperature and humidity monitoring (DHT22 → ESP32 → MQTT → Grafana)
- Light-based automation (BH1750 → ESP32 → MQTT → relay control)
- Simple ON/OFF control (Node-RED → MQTT → ESP32 → relay → LED)
Summary
Section titled “Summary”This section provided a complete, repeatable setup for an IoT demonstration environment:
- Deployed a 4-service Docker stack (Mosquitto, Node-RED, InfluxDB, Grafana)
- Configured each service with appropriate settings for demo use
- Verified MQTT communication using CLI tools and MQTT Explorer
- Created a simulated sensor data pipeline from Node-RED to InfluxDB
- Prepared the environment for customer demonstrations
The entire setup process takes under 10 minutes and requires only Docker on the host machine. This environment will be used throughout the training to support the project-based chapters (Chapters 02-05, 10-14).