Node-RED Docker 설치 가이드: 플로우 기반 프로그래밍 도구 – IoT와 홈 자동화의 핵심




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-REDn8nZapier
오픈소스✅ 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)

  1. Node-RED 편집기 열기
  2. 우측 상단 메뉴 → “Manage palette”
  3. “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-websocketHome Assistant 연동
node-red-node-mysqlMySQL 데이터베이스
node-red-contrib-influxdbInfluxDB 시계열 DB
node-red-contrib-telegrambotTelegram 봇
node-red-node-email이메일 발송
node-red-contrib-modbusModbus 프로토콜
node-red-contrib-opcuaOPC-UA 산업용

환경 변수 설정

주요 환경 변수

변수명설명기본값
TZ타임존UTC
NODE_RED_CREDENTIAL_SECRET인증 정보 암호화 키
NODE_RED_ENABLE_PROJECTS프로젝트 기능 활성화false
NODE_OPTIONSNode.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-REDn8nHome 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가 정답입니다!


참고 링크




댓글 남기기