Node-RED는 IBM이 개발하고 OpenJS Foundation이 관리하는 오픈소스 플로우 기반 프로그래밍 도구입니다. 브라우저에서 드래그 앤 드롭으로 하드웨어 장치, API, 온라인 서비스를 연결하여 IoT 솔루션을 구축할 수 있습니다. 4,000개 이상의 커뮤니티 노드와 MQTT, OPC-UA, Modbus 등 산업용 프로토콜을 지원하며, Home Assistant와 함께 홈 자동화의 핵심 도구로 사용됩니다.
Node-RED란?
Node-RED는 2013년 IBM의 Nick O’Leary와 Dave Conway-Jones가 개발한 플로우 기반 개발 도구입니다. Node.js 위에서 실행되며, 시각적 편집기에서 “노드”를 연결하여 데이터 흐름(플로우)을 만듭니다. 코딩 없이도 복잡한 자동화를 구현할 수 있어, 개발자부터 비개발자까지 폭넓게 사용됩니다.
플로우 기반 프로그래밍
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ MQTT │ ──▶ │ Function│ ──▶ │ Switch │ ──▶ │ Slack │
│ In │ │ (변환) │ │ (분기) │ │ 알림 │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
│
▼
┌─────────┐
│Database │
│ 저장 │
└─────────┘
왜 Node-RED인가?
| 특징 | Node-RED | n8n | Zapier |
|---|---|---|---|
| 오픈소스 | ✅ Apache 2.0 | ✅ Fair Code | ❌ |
| 가격 | 완전 무료 | 무료/유료 | 작업당 과금 |
| IoT 지원 | ✅ 최고 | ⚠️ 제한 | ❌ |
| MQTT | ✅ 네이티브 | ⚠️ | ❌ |
| 산업 프로토콜 | ✅ OPC-UA, Modbus | ❌ | ❌ |
| Raspberry Pi | ✅ 완벽 지원 | ⚠️ | ❌ |
| 실시간 처리 | ✅ | ⚠️ | ❌ |
주요 기능
🎨 시각적 편집기
- 브라우저 기반 플로우 편집기
- 드래그 앤 드롭 노드 연결
- 실시간 디버깅 및 테스트
- JSON 기반 플로우 내보내기/가져오기
🔌 4,000+ 커뮤니티 노드
- IoT: MQTT, OPC-UA, Modbus, BACnet
- 클라우드: AWS IoT, Azure IoT, Google Cloud
- 데이터베이스: MySQL, PostgreSQL, MongoDB, InfluxDB
- 메시징: Slack, Telegram, Discord, Email
- 홈 자동화: Home Assistant, Philips Hue, Sonos
- AI/ML: TensorFlow, IBM Watson
📡 IoT 프로토콜 지원
| 프로토콜 | 설명 | 용도 |
|---|---|---|
| MQTT | 경량 메시징 | IoT 센서, 홈 자동화 |
| OPC-UA | 산업 자동화 표준 | 제조업, PLC |
| Modbus | 산업용 통신 | 계측기, 센서 |
| TCP/UDP | 저수준 네트워킹 | 커스텀 장치 |
| WebSocket | 양방향 통신 | 실시간 대시보드 |
🖥️ 대시보드
node-red-dashboard: 시각화 UI 구축- 차트, 게이지, 버튼, 슬라이더
- 반응형 웹 인터페이스
- 실시간 데이터 업데이트
🏠 Home Assistant 통합
- WebSocket API 연동
- 센서/스위치 상태 모니터링
- 자동화 트리거 및 액션
- 양방향 데이터 흐름
사전 요구사항
- Docker 및 Docker Compose
- 최소 512MB RAM (권장 1GB+)
- Raspberry Pi도 지원 (ARM 이미지 제공)
- 웹 브라우저 (편집기 접속용)
Docker Compose 설치 방법
방법 1: 기본 설치
가장 간단한 단일 컨테이너 설정입니다:
version: '3.8'
services:
node-red:
image: nodered/node-red:latest
container_name: node-red
restart: unless-stopped
ports:
- "1880:1880"
environment:
- TZ=Asia/Seoul
volumes:
- node_red_data:/data
volumes:
node_red_data:
실행 후 http://localhost:1880으로 접속합니다.
방법 2: 사용자 권한 설정
version: '3.8'
services:
node-red:
image: nodered/node-red:latest
container_name: node-red
restart: unless-stopped
ports:
- "1880:1880"
environment:
- TZ=Asia/Seoul
volumes:
- ./node-red-data:/data
user: "1000:1000"
volumes:
node_red_data:
로컬 디렉토리 사용 시 권한 설정:
mkdir node-red-data
sudo chown -R 1000:1000 node-red-data
docker compose up -d
방법 3: MQTT 브로커와 함께 (IoT 스택)
version: '3.8'
services:
mosquitto:
image: eclipse-mosquitto:2
container_name: mosquitto
restart: unless-stopped
ports:
- "1883:1883"
- "9001:9001"
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
node-red:
image: nodered/node-red:latest
container_name: node-red
restart: unless-stopped
ports:
- "1880:1880"
environment:
- TZ=Asia/Seoul
volumes:
- node_red_data:/data
depends_on:
- mosquitto
networks:
- iot
influxdb:
image: influxdb:2
container_name: influxdb
restart: unless-stopped
ports:
- "8086:8086"
environment:
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_USERNAME=admin
- DOCKER_INFLUXDB_INIT_PASSWORD=adminpassword
- DOCKER_INFLUXDB_INIT_ORG=myorg
- DOCKER_INFLUXDB_INIT_BUCKET=iot
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=my-super-secret-token
volumes:
- influxdb_data:/var/lib/influxdb2
networks:
- iot
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
depends_on:
- influxdb
networks:
- iot
volumes:
node_red_data:
influxdb_data:
grafana_data:
networks:
iot:
driver: bridge
mosquitto/config/mosquitto.conf:
listener 1883
listener 9001
protocol websockets
allow_anonymous true
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
방법 4: 인증 활성화 (프로덕션)
version: '3.8'
services:
node-red:
image: nodered/node-red:latest
container_name: node-red
restart: unless-stopped
ports:
- "1880:1880"
environment:
- TZ=Asia/Seoul
- NODE_RED_CREDENTIAL_SECRET=${CREDENTIAL_SECRET}
volumes:
- ./node-red-data:/data
- ./settings.js:/data/settings.js:ro
volumes:
node_red_data:
settings.js (인증 설정):
module.exports = {
flowFile: 'flows.json',
flowFilePretty: true,
// 관리자 인증
adminAuth: {
type: "credentials",
users: [{
username: "admin",
// bcrypt 해시 (password: admin)
password: "$2b$08$wuAqPiKJlVN27eF5qJp.huQOK..n6fJwEtVPGNh.7qTKR8cYvLlCe",
permissions: "*"
}]
},
// HTTPS 설정 (선택)
// https: {
// key: require("fs").readFileSync('/data/certs/privkey.pem'),
// cert: require("fs").readFileSync('/data/certs/fullchain.pem')
// },
// 에디터 설정
editorTheme: {
projects: {
enabled: true
}
},
// 로깅
logging: {
console: {
level: "info",
metrics: false,
audit: false
}
}
}
비밀번호 해시 생성:
docker exec -it node-red npx node-red admin hash-pw
방법 5: 커스텀 노드 사전 설치
Dockerfile:
FROM nodered/node-red:latest
# 추가 노드 설치
RUN npm install --no-audit --no-update-notifier --no-fund --save \
node-red-dashboard \
node-red-contrib-home-assistant-websocket \
node-red-node-mysql \
node-red-contrib-influxdb \
node-red-contrib-telegrambot
docker-compose.yml:
version: '3.8'
services:
node-red:
build:
context: .
dockerfile: Dockerfile
container_name: node-red
restart: unless-stopped
ports:
- "1880:1880"
environment:
- TZ=Asia/Seoul
volumes:
- node_red_data:/data
volumes:
node_red_data:
빌드 및 실행:
docker compose build
docker compose up -d
방법 6: Traefik 리버스 프록시 연동
version: '3.8'
services:
node-red:
image: nodered/node-red:latest
container_name: node-red
restart: unless-stopped
environment:
- TZ=Asia/Seoul
volumes:
- node_red_data:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.nodered.rule=Host(`nodered.yourdomain.com`)"
- "traefik.http.routers.nodered.entrypoints=websecure"
- "traefik.http.routers.nodered.tls=true"
- "traefik.http.routers.nodered.tls.certresolver=letsencrypt"
- "traefik.http.services.nodered.loadbalancer.server.port=1880"
networks:
- nodered
- traefik
volumes:
node_red_data:
networks:
nodered:
driver: bridge
traefik:
external: true
방법 7: Home Assistant Addon 스타일
version: '3.8'
services:
homeassistant:
image: ghcr.io/home-assistant/home-assistant:stable
container_name: homeassistant
restart: unless-stopped
privileged: true
network_mode: host
environment:
- TZ=Asia/Seoul
volumes:
- ./homeassistant:/config
node-red:
image: nodered/node-red:latest
container_name: node-red
restart: unless-stopped
ports:
- "1880:1880"
environment:
- TZ=Asia/Seoul
volumes:
- node_red_data:/data
extra_hosts:
- "host.docker.internal:host-gateway"
mosquitto:
image: eclipse-mosquitto:2
container_name: mosquitto
restart: unless-stopped
ports:
- "1883:1883"
volumes:
- ./mosquitto/config:/mosquitto/config
volumes:
node_red_data:
샘플 플로우
1. MQTT 센서 데이터 처리
[
{
"id": "mqtt-in",
"type": "mqtt in",
"topic": "sensors/+/temperature",
"broker": "mosquitto",
"wires": [["json-parse"]]
},
{
"id": "json-parse",
"type": "json",
"action": "obj",
"wires": [["check-threshold"]]
},
{
"id": "check-threshold",
"type": "switch",
"property": "payload.value",
"rules": [
{"t": "gt", "v": "30"}
],
"wires": [["send-alert"]]
},
{
"id": "send-alert",
"type": "telegram sender",
"chatId": "-123456789",
"wires": [[]]
}
]
2. HTTP API → 데이터베이스 저장
[
{
"id": "http-in",
"type": "http in",
"url": "/api/data",
"method": "post",
"wires": [["validate", "http-response"]]
},
{
"id": "validate",
"type": "function",
"func": "if (!msg.payload.sensor_id) {\n msg.statusCode = 400;\n msg.payload = {error: 'sensor_id required'};\n return [null, msg];\n}\nreturn [msg, null];",
"wires": [["influx-out"], ["http-response"]]
},
{
"id": "influx-out",
"type": "influxdb out",
"measurement": "sensor_data",
"wires": []
},
{
"id": "http-response",
"type": "http response",
"wires": []
}
]
3. 대시보드 게이지
[
{
"id": "mqtt-temp",
"type": "mqtt in",
"topic": "home/living-room/temperature",
"wires": [["gauge"]]
},
{
"id": "gauge",
"type": "ui_gauge",
"group": "home-dashboard",
"name": "거실 온도",
"unit": "°C",
"min": 0,
"max": 50,
"wires": []
}
]
4. 스케줄 기반 자동화
[
{
"id": "cron-trigger",
"type": "inject",
"repeat": "",
"crontab": "0 8 * * 1-5",
"wires": [["morning-routine"]]
},
{
"id": "morning-routine",
"type": "function",
"func": "msg.payload = {\n action: 'turn_on',\n entity_id: 'light.living_room'\n};\nreturn msg;",
"wires": [["ha-service"]]
},
{
"id": "ha-service",
"type": "api-call-service",
"server": "home-assistant",
"domain": "light",
"service": "turn_on",
"wires": [[]]
}
]
추가 노드 설치
팔레트 관리자 (UI)
- Node-RED 편집기 열기
- 우측 상단 메뉴 → “Manage palette”
- “Install” 탭에서 노드 검색 및 설치
명령줄 설치
# 컨테이너 내부에서 설치
docker exec -it node-red npm install node-red-dashboard
# 또는 스크립트로 일괄 설치
docker exec -it node-red sh -c '
npm install --no-audit --no-update-notifier --no-fund --save \
node-red-dashboard \
node-red-contrib-home-assistant-websocket \
node-red-node-email \
node-red-contrib-telegrambot
'
# 재시작
docker restart node-red
인기 노드 목록
| 노드 | 설명 |
|---|---|
node-red-dashboard | 시각화 대시보드 |
node-red-contrib-home-assistant-websocket | Home Assistant 연동 |
node-red-node-mysql | MySQL 데이터베이스 |
node-red-contrib-influxdb | InfluxDB 시계열 DB |
node-red-contrib-telegrambot | Telegram 봇 |
node-red-node-email | 이메일 발송 |
node-red-contrib-modbus | Modbus 프로토콜 |
node-red-contrib-opcua | OPC-UA 산업용 |
환경 변수 설정
주요 환경 변수
| 변수명 | 설명 | 기본값 |
|---|---|---|
TZ | 타임존 | UTC |
NODE_RED_CREDENTIAL_SECRET | 인증 정보 암호화 키 | – |
NODE_RED_ENABLE_PROJECTS | 프로젝트 기능 활성화 | false |
NODE_OPTIONS | Node.js 옵션 | – |
메모리 설정
environment:
- NODE_OPTIONS=--max-old-space-size=512
업그레이드 및 백업
버전 업그레이드
# 최신 이미지 풀
docker compose pull
# 재시작
docker compose down
docker compose up -d
플로우 백업
# 플로우 파일 백업
docker cp node-red:/data/flows.json ./backup/flows_$(date +%Y%m%d).json
# 전체 데이터 디렉토리 백업
docker run --rm -v node_red_data:/data -v $(pwd)/backup:/backup \
alpine tar czf /backup/nodered_backup_$(date +%Y%m%d).tar.gz /data
플로우 복원
# 플로우 파일 복원
docker cp ./backup/flows.json node-red:/data/flows.json
docker restart node-red
문제 해결
권한 오류
# 데이터 디렉토리 권한 수정
sudo chown -R 1000:1000 ./node-red-data
노드 설치 실패
# 캐시 정리 후 재설치
docker exec -it node-red npm cache clean --force
docker exec -it node-red npm install node-red-dashboard
MQTT 연결 실패
- 브로커 주소 확인 (Docker 네트워크에서는 컨테이너 이름 사용)
- 포트 및 인증 정보 확인
- 네트워크 연결 테스트:
docker exec -it node-red ping mosquitto
메모리 부족
services:
node-red:
deploy:
resources:
limits:
memory: 1G
사용 사례
1. IoT 데이터 파이프라인
- 센서 데이터 수집 (MQTT)
- 데이터 변환 및 검증
- 시계열 DB 저장 (InfluxDB)
- 대시보드 시각화 (Grafana)
2. 홈 자동화
- Home Assistant 연동
- 조명/온도/보안 자동화
- 음성 비서 통합
- 에너지 모니터링
3. 산업 자동화
- PLC 연동 (Modbus, OPC-UA)
- 실시간 모니터링
- 알람 및 알림
- 데이터 로깅
4. API 통합
- 웹훅 수신/발송
- REST API 오케스트레이션
- 데이터 변환 및 라우팅
- 서비스 간 연동
도구 비교
| 기능 | Node-RED | n8n | Home Assistant |
|---|---|---|---|
| IoT 프로토콜 | ✅ 최고 | ⚠️ 제한 | ⚠️ 제한 |
| 시각적 편집 | ✅ | ✅ | ⚠️ YAML |
| 대시보드 | ✅ | ❌ | ✅ |
| 실시간 처리 | ✅ | ⚠️ | ✅ |
| 비즈니스 자동화 | ⚠️ | ✅ | ❌ |
| 커뮤니티 노드 | 4,000+ | 400+ | 2,000+ |
| Raspberry Pi | ✅ | ⚠️ | ✅ |
결론
Node-RED는 다음과 같은 경우에 최적입니다:
- IoT 프로젝트: 센서, 하드웨어, 프로토콜 연동
- 홈 자동화: Home Assistant와 함께 복잡한 자동화 구현
- 산업 자동화: OPC-UA, Modbus 등 산업 프로토콜 지원
- 프로토타이핑: 빠른 아이디어 검증 및 MVP 개발
- 교육: 시각적 프로그래밍으로 프로그래밍 개념 학습
IBM이 개발하고 OpenJS Foundation이 관리하는 검증된 프로젝트로, Raspberry Pi부터 엔터프라이즈 서버까지 어디서나 실행됩니다. 무료이면서 강력한 IoT 자동화 도구를 찾고 있다면 Node-RED가 정답입니다!