Instalación de Node-RED: Programación por Flujos en Linux
Node-RED es una herramienta de programación visual basada en flujos que permite conectar dispositivos IoT, APIs web y servicios en línea mediante una interfaz de arrastre y suelta. Construido sobre Node.js, facilita la creación de integraciones complejas sin necesidad de escribir código, siendo especialmente popular en proyectos de automatización industrial, IoT y orquestación de servicios en servidores Linux.
Requisitos Previos
- Ubuntu 20.04/22.04 o CentOS/Rocky Linux 8+
- Node.js 18 LTS o superior
- npm 8+ (incluido con Node.js)
- Al menos 512 MB de RAM
- Acceso root o usuario con privilegios sudo
Instalación de Node-RED
Instalación con el script oficial (recomendada)
# El script oficial instala Node.js, npm y Node-RED
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
# El script preguntará si instalar las herramientas de Raspberry Pi:
# Responder NO en un servidor Linux estándar
# Habilitar e iniciar el servicio
sudo systemctl enable nodered.service
sudo systemctl start nodered.service
# Verificar estado
sudo systemctl status nodered.service
# Acceder a la interfaz web:
# http://IP_DEL_SERVIDOR:1880
Instalación manual con npm
# Instalar Node.js 20 LTS
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
# Verificar versiones
node --version
npm --version
# Instalar Node-RED globalmente
sudo npm install -g --unsafe-perm node-red
# Verificar instalación
node-red --version
# Iniciar Node-RED (el editor escucha en el puerto 1880)
node-red &
# Para uso en producción, crear usuario dedicado
sudo useradd -m -r -s /bin/bash nodered
sudo -u nodered node-red &
Instalación con Docker
# Ejecutar Node-RED con Docker
docker run -d \
--name nodered \
-p 1880:1880 \
-v nodered_data:/data \
-e TZ=Europe/Madrid \
--restart unless-stopped \
nodered/node-red:latest
# Ver logs de inicio
docker logs nodered -f
Configuración Inicial
Configurar la seguridad y las opciones de Node-RED:
# El archivo de configuración está en ~/.node-red/settings.js
# En instalación con servicio: /root/.node-red/settings.js o /home/nodered/.node-red/settings.js
nano ~/.node-red/settings.js
Configuración básica de seguridad:
module.exports = {
// Puerto de escucha del editor
uiPort: process.env.PORT || 1880,
// Directorio de flujos
userDir: '/home/nodered/.node-red',
flowFile: 'flows.json',
// Credenciales encriptadas
credentialSecret: "mi_clave_de_encriptacion_segura",
// Autenticación en la interfaz web (IMPORTANTE: habilitar en producción)
adminAuth: {
type: "credentials",
users: [
{
username: "admin",
// Generar hash: node-red-admin hash-pw
password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
permissions: "*"
},
{
username: "readonly",
password: "$2a$08$HASH_PASSWORD_LECTURA",
permissions: "read"
}
]
},
// Configurar tiempo de sesión (en milisegundos)
adminAuth: {
sessionExpiryTime: 86400, // 24 horas en segundos
},
// Logging
logging: {
console: {
level: "info",
metrics: false,
audit: false
}
},
// Editor de código habilitado
codeEditor: {
lib: {
// Usar Monaco editor (mejor experiencia)
editor: "monaco"
}
}
}
Generar la contraseña hasheada:
# Generar hash de contraseña para la configuración
node-red-admin hash-pw
# Introducir la contraseña cuando se pide
# Copiar el hash generado a settings.js
# Reiniciar Node-RED para aplicar cambios
sudo systemctl restart nodered.service
Creación de Flujos
Los flujos se crean visualmente, pero se almacenan como JSON:
# Importar un flujo de ejemplo via API REST de Node-RED
# Primero obtener el token de sesión (si la autenticación está habilitada)
TOKEN=$(curl -s -X POST http://localhost:1880/auth/token \
-H "Content-Type: application/json" \
-d '{"client_id":"node-red-admin","grant_type":"password","username":"admin","password":"contraseña"}' \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
# Importar flujo via API
curl -X POST http://localhost:1880/flows \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"flows": [
{
"id": "tab1",
"type": "tab",
"label": "Mi Primer Flujo"
},
{
"id": "inject1",
"type": "inject",
"z": "tab1",
"name": "Cada minuto",
"repeat": "60",
"once": true,
"wires": [["function1"]]
},
{
"id": "function1",
"type": "function",
"z": "tab1",
"name": "Procesar datos",
"func": "// Código JavaScript del nodo función\nvar ahora = new Date();\nmsg.payload = {\n timestamp: ahora.toISOString(),\n hora: ahora.getHours(),\n minuto: ahora.getMinutes()\n};\nreturn msg;",
"wires": [["debug1"]]
},
{
"id": "debug1",
"type": "debug",
"z": "tab1",
"name": "Ver resultado",
"active": true,
"wires": []
}
]
}'
Ejemplo de flujo para monitorización del servidor:
// Código del nodo Function para monitorizar el servidor
// Este código se pega en el nodo "Función" del editor visual
const { execSync } = require('child_process');
// Obtener uso de CPU (valor de 0-100)
const cpuInfo = execSync("top -bn1 | grep 'Cpu(s)' | awk '{print $2}'").toString().trim();
const cpu = parseFloat(cpuInfo) || 0;
// Obtener uso de memoria
const memInfo = execSync("free | awk '/^Mem:/{printf \"%.1f\", $3/$2 * 100}'").toString().trim();
const memoria = parseFloat(memInfo) || 0;
// Obtener uso de disco
const discoInfo = execSync("df / | awk 'NR==2{print $5}' | tr -d '%'").toString().trim();
const disco = parseInt(discoInfo) || 0;
// Construir el payload de la métrica
msg.payload = {
timestamp: new Date().toISOString(),
host: require('os').hostname(),
cpu_porcentaje: cpu,
memoria_porcentaje: memoria,
disco_porcentaje: disco,
alerta: (cpu > 80 || memoria > 85 || disco > 90)
};
// Añadir nivel de severidad
if (msg.payload.alerta) {
msg.topic = "alerta/servidor/" + require('os').hostname();
} else {
msg.topic = "metricas/servidor/" + require('os').hostname();
}
return msg;
Integración con MQTT
Conectar Node-RED con un broker MQTT:
# Instalar el paquete MQTT adicional si es necesario
# (node-red-contrib-mqtt-broker para broker integrado)
cd ~/.node-red && npm install node-red-contrib-mqtt-broker
sudo systemctl restart nodered.service
Configuración de flujo MQTT en JSON:
[
{
"id": "mqtt-in-sensores",
"type": "mqtt in",
"name": "Recibir datos sensores",
"topic": "casa/+/datos",
"broker": "broker-local",
"wires": [["parse-json"]]
},
{
"id": "parse-json",
"type": "json",
"name": "Parsear JSON",
"action": "obj",
"wires": [["verificar-temperatura"]]
},
{
"id": "verificar-temperatura",
"type": "switch",
"name": "¿Temperatura alta?",
"property": "payload.temperatura",
"rules": [
{"t": "gt", "v": "28"},
{"t": "else"}
],
"wires": [["enviar-alerta"], ["almacenar-dato"]]
},
{
"id": "broker-local",
"type": "mqtt-broker",
"name": "Mosquitto Local",
"broker": "localhost",
"port": "1883",
"clientid": "nodered-client",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"credentials": {
"user": "nodered_user",
"password": "mqtt_password"
}
}
]
Nodos de Dashboard
Crear interfaces visuales con node-red-dashboard:
# Instalar el módulo de dashboard
cd ~/.node-red
npm install node-red-dashboard
sudo systemctl restart nodered.service
# El dashboard estará disponible en: http://servidor:1880/ui
Flujo de ejemplo para dashboard de temperatura:
// Nodo Function para preparar datos del gráfico
// El payload de entrada: {"temperatura": 22.5, "humedad": 60}
// Redirigir temperatura al gauge del dashboard
var msgTemperatura = {
payload: msg.payload.temperatura,
topic: "Temperatura (°C)"
};
// Redirigir humedad al gauge del dashboard
var msgHumedad = {
payload: msg.payload.humedad,
topic: "Humedad (%)"
};
// Devolver múltiples salidas (el nodo Function puede tener varias)
return [msgTemperatura, msgHumedad];
Endpoints de API REST
Crear APIs HTTP con Node-RED:
[
{
"id": "http-endpoint",
"type": "http in",
"name": "GET /api/estado",
"url": "/api/estado",
"method": "get",
"wires": [["get-estado"]]
},
{
"id": "get-estado",
"type": "function",
"name": "Obtener estado del sistema",
"func": "const os = require('os');\n\nmsg.payload = {\n uptime_segundos: os.uptime(),\n memoria_libre_mb: Math.round(os.freemem() / 1024 / 1024),\n memoria_total_mb: Math.round(os.totalmem() / 1024 / 1024),\n cpus: os.cpus().length,\n load: os.loadavg(),\n hostname: os.hostname()\n};\n\nmsg.statusCode = 200;\nreturn msg;",
"wires": [["http-response"]]
},
{
"id": "http-response",
"type": "http response",
"name": "Responder JSON",
"statusCode": "",
"headers": {"Content-Type": "application/json"},
"wires": []
}
]
# Probar el endpoint creado
curl -s http://localhost:1880/api/estado | python3 -m json.tool
# Crear endpoint POST para recibir webhooks
# (añadir en el flujo un nodo "http in" con method: POST y la URL deseada)
Nodos Personalizados
Instalar y usar nodos de la comunidad:
# Instalar nodos desde la paleta de Node-RED
# Herramientas > Gestionar paleta > Instalar
# O instalar directamente via npm
cd ~/.node-red
# Nodo para InfluxDB
npm install node-red-contrib-influxdb
# Nodo para notificaciones Telegram
npm install node-red-contrib-telegrambot
# Nodo para bases de datos SQLite
npm install node-red-node-sqlite
# Nodo para email
npm install node-red-node-email
# Nodo para monitorización de sitios web
npm install node-red-node-ping
sudo systemctl restart nodered.service
# Ver los nodos instalados
npm list --depth=0 --prefix ~/.node-red
Despliegue en Producción
Configuración para entornos de producción:
# 1. Configurar Nginx como proxy inverso con SSL
sudo cat > /etc/nginx/sites-available/nodered << 'EOF'
server {
listen 80;
server_name nodered.mi-dominio.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name nodered.mi-dominio.com;
ssl_certificate /etc/letsencrypt/live/nodered.mi-dominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nodered.mi-dominio.com/privkey.pem;
# Editor de Node-RED (acceso restringido)
location / {
# Limitar acceso al editor solo desde IPs de administración
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
proxy_pass http://127.0.0.1:1880;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# WebSocket para actualizaciones en tiempo real del editor
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Dashboard público (accesible externamente)
location /ui {
proxy_pass http://127.0.0.1:1880;
proxy_set_header Host $host;
}
# Endpoints de API pública
location /api/ {
proxy_pass http://127.0.0.1:1880;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/nodered /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# 2. Configurar límites del sistema para el servicio
sudo mkdir -p /etc/systemd/system/nodered.service.d/
cat > /etc/systemd/system/nodered.service.d/override.conf << 'EOF'
[Service]
# Límites de recursos
LimitNOFILE=65535
# Reiniciar automáticamente si falla
Restart=always
RestartSec=10
EOF
sudo systemctl daemon-reload && sudo systemctl restart nodered.service
Solución de Problemas
Node-RED no arranca (error de Node.js):
# Verificar versión de Node.js
node --version # Debe ser 18+ para la versión actual de Node-RED
# Ver logs del servicio
sudo journalctl -u nodered -n 50
# Iniciar manualmente para ver errores
sudo -u nodered node-red --userDir /home/nodered/.node-red
Los flujos no se despliegan (error en el editor):
# Ver los logs del servidor de Node-RED en tiempo real
tail -f ~/.node-red/node-red.log
# Verificar que el archivo de flujos no tiene errores JSON
python3 -m json.tool ~/.node-red/flows.json
Error de credenciales MQTT:
# Verificar la configuración del broker en el nodo MQTT
# El broker debe ser accesible desde el servidor
telnet localhost 1883
# Ver los logs del broker Mosquitto
sudo journalctl -u mosquitto -n 20
El dashboard no carga:
# Verificar que el módulo de dashboard está instalado
ls ~/.node-red/node_modules | grep dashboard
# Reinstalar si es necesario
cd ~/.node-red && npm install node-red-dashboard
sudo systemctl restart nodered.service
Conclusión
Node-RED democratiza la integración de sistemas y dispositivos IoT al eliminar la necesidad de escribir código para conectar servicios, sensores y APIs mediante una interfaz visual intuitiva. Su modelo de programación por flujos es especialmente poderoso para prototipar y desplegar rápidamente integraciones que de otra forma requerirían desarrollo significativo. La combinación de MQTT, las extensas librerías de nodos de la comunidad y los endpoints HTTP nativos convierte a Node-RED en una plataforma de orquestación de servicios completa para proyectos IoT y automatización en servidores Linux de producción.


