跳转到内容

快速演示环境搭建

快速演示环境搭建

本节介绍如何快速搭建完整的 IoT 演示环境,面向客户展示 PoC 能力。学习完成后,您将能够:

  • 在 5 分钟内搭建完整的 IoT 技术栈
  • 使用一键脚本自动完成部署
  • 验证各个组件的运行状态
  • 向客户展示完整的 IoT 数据流
  • 一台 Linux 服务器(Ubuntu 20.04+ 推荐)
  • 服务器最低配置:1C2G(推荐 2C4G)
  • 已安装 Docker 和 Docker Compose
  • 开放必要端口(1883, 1880, 8086, 3000, 9000)
  • 稳定的网络连接

创建一个完整的部署脚本 deploy-iot-stack.sh

#!/bin/bash
# Node-RED & ESP32 IoT Stack - 一键部署脚本
# 用于快速搭建 PoC 演示环境
set -e
# 颜色定义
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE} IoT Stack 一键部署脚本 v1.0${NC}"
echo -e "${BLUE}========================================${NC}"
# 检查 Docker
echo -e "\n${YELLOW}[1/5] 检查 Docker 环境...${NC}"
if command -v docker &> /dev/null; then
echo -e "${GREEN}✓ Docker 已安装: $(docker --version)${NC}"
else
echo -e "${YELLOW} 安装 Docker...${NC}"
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
fi
# 检查 Docker Compose
if command -v docker-compose &> /dev/null; then
echo -e "${GREEN}✓ Docker Compose 已安装: $(docker-compose --version)${NC}"
else
echo -e "${YELLOW} 安装 Docker Compose...${NC}"
sudo apt-get update
sudo apt-get install -y docker-compose-plugin
fi
# 创建项目目录
echo -e "\n${YELLOW}[2/5] 创建项目目录...${NC}"
mkdir -p ~/iot-demo
cd ~/iot-demo
# 创建目录结构
mkdir -p mosquitto/{config,data,log}
mkdir -p nodered/data
mkdir -p influxdb/{data,config}
mkdir -p grafana/data
mkdir -p portainer/data
# 创建 Mosquitto 配置文件
cat > mosquitto/config/mosquitto.conf << 'EOF'
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
listener 1883
allow_anonymous true
EOF
echo -e "${GREEN}✓ 目录结构创建完成${NC}"
# 创建 docker-compose.yml
echo -e "\n${YELLOW}[3/5] 创建 Docker Compose 配置...${NC}"
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
mosquitto:
image: eclipse-mosquitto:2
container_name: iot-mosquitto
restart: unless-stopped
ports:
- "1883:1883"
- "9001:9001"
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
nodered:
image: nodered/node-red:latest
container_name: iot-nodered
restart: unless-stopped
ports:
- "1880:1880"
volumes:
- ./nodered/data:/data
environment:
- TZ=Asia/Shanghai
influxdb:
image: influxdb:2
container_name: iot-influxdb
restart: unless-stopped
ports:
- "8086:8086"
volumes:
- ./influxdb/data:/var/lib/influxdb2
- ./influxdb/config:/etc/influxdb2
grafana:
image: grafana/grafana:latest
container_name: iot-grafana
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- ./grafana/data:/var/lib/grafana
portainer:
image: portainer/portainer-ce:latest
container_name: iot-portainer
restart: unless-stopped
ports:
- "9000:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./portainer/data:/data
networks:
default:
name: iot-network
driver: bridge
EOF
echo -e "${GREEN}✓ docker-compose.yml 创建完成${NC}"
# 启动服务
echo -e "\n${YELLOW}[4/5] 启动 IoT 服务...${NC}"
docker-compose pull
docker-compose up -d
echo -e "${GREEN}✓ 所有服务已启动${NC}"
# 等待服务就绪
echo -e "\n${YELLOW}[5/5] 等待服务就绪...${NC}"
sleep 10
# 验证服务状态
echo -e "\n${BLUE}========================================${NC}"
echo -e "${BLUE} IoT Stack 部署完成!${NC}"
echo -e "${BLUE}========================================${NC}"
# 获取服务器 IP
SERVER_IP=$(curl -s ifconfig.me 2>/dev/null || hostname -I | awk '{print $1}')
echo -e "\n${GREEN}访问地址:${NC}"
echo -e "${GREEN} Node-RED: http://${SERVER_IP}:1880${NC}"
echo -e "${GREEN} Grafana: http://${SERVER_IP}:3000${NC}"
echo -e "${GREEN} InfluxDB: http://${SERVER_IP}:8086${NC}"
echo -e "${GREEN} Portainer: http://${SERVER_IP}:9000${NC}"
echo -e "${GREEN} MQTT: ${SERVER_IP}:1883${NC}"
echo -e "\n${GREEN}默认凭据:${NC}"
echo -e "${GREEN} Grafana: admin / admin${NC}"
echo -e "${GREEN} Portainer: 首次访问设置密码${NC}"
echo -e "\n${YELLOW}管理命令:${NC}"
echo -e "${YELLOW} 查看状态: docker-compose ps${NC}"
echo -e "${YELLOW} 查看日志: docker-compose logs -f${NC}"
echo -e "${YELLOW} 停止服务: docker-compose stop${NC}"
echo -e "${YELLOW} 启动服务: docker-compose start${NC}"
echo -e "${YELLOW} 重启服务: docker-compose restart${NC}"
echo -e "${YELLOW} 删除服务: docker-compose down${NC}"
# 输出服务状态
echo -e "\n${BLUE}服务运行状态:${NC}"
docker-compose ps
Terminal window
# 赋予执行权限
chmod +x deploy-iot-stack.sh
# 执行部署
./deploy-iot-stack.sh

首次访问 InfluxDB Web UI (http://<server-ip>:8086):

# 创建 InfluxDB 初始化脚本
cat > influxdb/setup-influxdb.sh << 'SCRIPT'
#!/bin/bash
# 等待 InfluxDB 就绪
echo "Waiting for InfluxDB..."
until curl -s http://localhost:8086/health > /dev/null 2>&1; do
sleep 2
done
# 初始化 InfluxDB
docker exec iot-influxdb influx setup \
--username admin \
--password iotdemo2024 \
--org iot-demo \
--bucket nodered \
--force
echo "InfluxDB initialized successfully!"
echo " Organization: iot-demo"
echo " Bucket: nodered"
echo " Username: admin"
SCRIPT
chmod +x influxdb/setup-influxdb.sh
./influxdb/setup-influxdb.sh
Terminal window
# 添加 InfluxDB 数据源
curl -X POST http://admin:admin@localhost:3000/api/datasources \
-H "Content-Type: application/json" \
-d '{
"name": "InfluxDB",
"type": "influxdb",
"url": "http://influxdb:8086",
"access": "proxy",
"basicAuth": false,
"jsonData": {
"version": "Flux",
"organization": "iot-demo",
"defaultBucket": "nodered"
},
"secureJsonData": {
"token": "your-influxdb-token"
}
}'

nodered/data/flows.json 中添加预设 Flow:

[
{
"id": "demo-flow",
"type": "tab",
"label": "IoT Demo Flow"
},
{
"id": "mqtt-input",
"type": "mqtt in",
"z": "demo-flow",
"name": "MQTT Input",
"topic": "sensor/#",
"qos": "1",
"datatype": "auto",
"broker": "mqtt-broker",
"x": 120,
"y": 100,
"wires": [["json-parse"]]
},
{
"id": "json-parse",
"type": "json",
"z": "demo-flow",
"name": "Parse JSON",
"property": "payload",
"action": "obj",
"x": 260,
"y": 100,
"wires": [["influxdb-out"]]
},
{
"id": "influxdb-out",
"type": "influxdb out",
"z": "demo-flow",
"name": "Save to InfluxDB",
"influxdb": "influxdb-config",
"measurement": "sensor_data",
"x": 400,
"y": 100,
"wires": []
},
{
"id": "mqtt-broker",
"type": "mqtt-broker",
"name": "Local Mosquitto",
"broker": "mosquitto",
"port": "1883"
},
{
"id": "influxdb-config",
"type": "influxdb",
"name": "InfluxDB",
"host": "influxdb",
"port": "8086",
"database": "nodered"
}
]
Terminal window
# 1. 验证 Docker 容器状态
docker-compose ps
# 2. 验证 MQTT 服务
mosquitto_sub -h localhost -t "test" &
mosquitto_pub -h localhost -t "test" -m "Hello IoT"
# 应收到消息:Hello IoT
# 3. 验证 Node-RED
curl -s http://localhost:1880 | grep -o "Node-RED"
# 应输出:Node-RED
# 4. 验证 InfluxDB
curl -s http://localhost:8086/health
# 应返回:{"status":"pass","version":"2.x"}
# 5. 验证 Grafana
curl -s http://localhost:3000/api/health
# 应返回:{"database":"ok"}
ESP32 传感器 → MQTT (1883) → Mosquitto
Node-RED (订阅 sensor/#)
InfluxDB (时序存储)
Grafana (可视化仪表板)
┌─────────────────────────────────────────────────┐
│ 客户笔记本电脑 │
│ ┌──────────────────────────────────────────┐ │
│ │ 浏览器访问: │ │
│ │ ├─ http://<server>:1880 → Node-RED │ │
│ │ ├─ http://<server>:3000 → Grafana │ │
│ │ ├─ http://<server>:8086 → InfluxDB │ │
│ │ └─ http://<server>:9000 → Portainer │ │
│ └──────────────────────────────────────────┘ │
└────────────────────────┬────────────────────────┘
│ 网络 (SSH/HTTP)
┌────────────────────────┴────────────────────────┐
│ 云服务器 / 本地服务器 │
│ ┌──────────────────────────────────────────┐ │
│ │ Docker Compose IoT Stack │ │
│ │ ├─ Mosquitto (1883) │ │
│ │ ├─ Node-RED (1880) │ │
│ │ ├─ InfluxDB (8086) │ │
│ │ ├─ Grafana (3000) │ │
│ │ └─ Portainer (9000) │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
  1. 开场(30 秒)

    • “This is our IoT technology stack, deployed in just 5 minutes”
    • “All components run in Docker containers for easy management”
  2. 核心流程演示(2 分钟)

    • 展示 Node-RED Flow 处理 MQTT 数据
    • 展示实时数据写入 InfluxDB
    • 展示 Grafana 仪表板数据可视化
  3. 技术优势说明(1 分钟)

    • 容器化带来的可移植性
    • 一键部署的效率优势
    • 完整的端到端 IoT 方案
  4. 客户互动(30 秒)

    • 让客户发送测试 MQTT 消息
    • 实时观察数据变化

推荐做法:

  • 提前准备演示脚本和 Flow
  • 使用预设测试数据生成器
  • 准备 Grafana 仪表板模板
  • 确保网络环境稳定(备用热点)
  • 提前录制演示视频作为备份

避免做法:

  • 在客户面前执行安装过程
  • 依赖不稳定的网络下载镜像
  • 忘记配置安全策略
  • 使用 weak 密码
  1. 5 分钟即可完成完整 IoT 栈部署
  2. 一键脚本自动化所有安装和配置
  3. 开箱即用的 Node-RED Flow 和 Grafana 模板
  4. 适合 PoC 验证和客户演示场景
  5. 支持多种部署方式(云服务器/本地/边缘)