Node-RED в Docker Compose: готовый файл
Node-RED хорош ровно до момента, когда вы поставили его «быстро попробовать» через npm install -g node-red и через месяц не можете вспомнить, где лежат потоки, как их бэкапить и почему после перезагрузки сервера редактор не поднимается сам. Docker Compose снимает все три проблемы разом: контейнер стартует вместе с системой, данные лежат в именованном томе, а обновление — это docker compose pull и один рестарт. Ниже — рабочий файл, который можно взять как есть и адаптировать под свою автоматизацию.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Зачем Node-RED в контейнере, а не как сервис на хосте
Node-RED — это визуальный редактор потоков на Node.js: узлы (nodes) соединяются проводами, через них идут сообщения msg.payload. Типичный сценарий — забрать данные с MQTT-топика, обработать функцией на JavaScript, дернуть HTTP API или отправить команду в Home Assistant. Именно поэтому Node-RED почти всегда стоит рядом с Home Assistant, а не вместо него: HA хранит состояние умного дома и графический интерфейс для людей, Node-RED — гибкую логику для сценариев, которые в конструкторе автоматизаций HA неудобно выразить (сложные условия, циклы, интеграция со сторонними API).
Плюсы контейнера конкретно для Node-RED:
- Версия Node.js фиксирована внутри образа — не зависит от того, что стоит на хосте.
- Все npm-пакеты для дополнительных узлов (palette) ставятся через
npm installвнутри контейнера и не засоряют систему. - Один
docker compose down && docker compose up -d— и вы откатились на предыдущий образ, если новая версия что-то сломала. - Изоляция: если в поток случайно попадет команда
execиз непроверенного flow с flows.nodered.org, она выполнится внутри контейнера, а не на хосте.
Минус — сетевые интеграции (обнаружение устройств по mDNS/SSDP, некоторые Bluetooth-узлы) в Docker чуть сложнее настраивать, чем на голом хосте. Для UDP/mDNS-зависимых узлов ниже показан вариант с network_mode: host.
Готовый docker-compose.yml
Базовый вариант с bridge-сетью и Traefik-совместимыми лейблами (можно убрать, если проксируете иначе):
services:
nodered:
image: nodered/node-red:latest
container_name: nodered
restart: unless-stopped
environment:
- TZ=Europe/Moscow
- NODE_RED_ENABLE_PROJECTS=true
ports:
- "1880:1880"
volumes:
- nodered_data:/data
networks:
- proxy
networks:
proxy:
external: true
volumes:
nodered_data:
Если Node-RED должен видеть устройства в локальной сети напрямую (Sonoff-девайсы, mDNS-обнаружение, некоторые Zigbee-донглы через USB на этом же хосте), используйте network_mode: host — тогда блок ports и networks не нужен:
services:
nodered:
image: nodered/node-red:latest
container_name: nodered
restart: unless-stopped
network_mode: host
environment:
- TZ=Europe/Moscow
volumes:
- nodered_data:/data
volumes:
nodered_data:
Важно: конкретный тег образа стоит зафиксировать явно (nodered/node-red:3.1.9-18 вместо latest), как только редактор стабильно настроен — так обновления не прилетят незаметно и не сломают палитру узлов между релизами.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПервый запуск и настройка пароля
mkdir -p ~/nodered && cd ~/nodered
# сюда положите docker-compose.yml из раздела выше
docker compose up -d
docker compose logs -f nodered
По умолчанию редактор на порту 1880 открыт без пароля — для сервера, торчащего в интернет, это неприемлемо. Пароль задается через settings.js, который лучше вынести отдельным томом, чтобы не терять при обновлении образа:
# сгенерировать bcrypt-хеш пароля
docker run --rm nodered/node-red:latest node -e \
"console.log(require('bcryptjs').hashSync(process.argv[1], 8))" 'ваш-пароль'
Полученный хеш вставьте в settings.js внутри тома /data (файл создается автоматически при первом запуске):
module.exports = {
adminAuth: {
type: "credentials",
users: [{
username: "admin",
password: "$2a$08$вставьте.сюда.полученный.хеш",
permissions: "*"
}]
},
// остальные настройки settings.js остаются как есть
}
После правки перезапустите контейнер: docker compose restart nodered. Без этого шага любой, кто найдет открытый порт 1880, сможет через узел exec выполнить произвольный код на сервере — это не гипотетическая угроза, а стандартный вектор атаки на незащищенные Node-RED-инстансы.
Интеграция с Home Assistant
Два рабочих способа связать Node-RED с HA:
1. Node-RED Companion (рекомендуется) — интеграция ставится со стороны Home Assistant (Настройки → Устройства и службы → Добавить интеграцию → Node-RED Companion), а в Node-RED устанавливается пакет node-red-contrib-home-assistant-websocket через встроенный Palette Manager (Menu → Manage palette → Install). После этого в редакторе появляются узлы events: state, call service, current state — события HA прилетают в потоки в реальном времени через WebSocket, без опроса.
2. Долгоживущий токен + REST/WebSocket напрямую — если нужен более низкоуровневый контроль. В HA: профиль пользователя → Long-Lived Access Tokens → создать токен, затем использовать его в узле ha-server companion-пакета или в обычном HTTP-запросе с заголовком Authorization: Bearer <токен>.
Если Home Assistant и Node-RED в одной docker-сети, адрес сервера в конфиге узла ha-server — это имя контейнера HA (http://homeassistant:8123), а не localhost. Если стоят на разных хостах или HA не в Docker — обычный URL с портом 8123.
Пример готового compose-файла для самого Home Assistant, если его еще нет: Home Assistant в Docker Compose. Там же описан том для конфигурации и таймзона, которую важно синхронизировать с Node-RED, иначе триггеры по времени суток разъедутся на пару часов.
Обратный прокси и HTTPS
Открывать 1880 порт наружу без TLS — плохая идея, даже с паролем: креды и cookie сессии идут в открытом виде. Проще всего завести Node-RED за Traefik или Caddy с автоматическим сертификатом.
Пример лейблов для Traefik (добавляются в сервис nodered в первом варианте compose-файла):
labels:
- "traefik.enable=true"
- "traefik.http.routers.nodered.rule=Host(`flows.example.com`)"
- "traefik.http.routers.nodered.entrypoints=websecure"
- "traefik.http.routers.nodered.tls.certresolver=letsencrypt"
- "traefik.http.services.nodered.loadbalancer.server.port=1880"
Node-RED использует WebSocket для живого обновления редактора и для узлов ha-server — убедитесь, что прокси не режет upgrade-заголовки. У Traefik это работает из коробки, у голого Nginx нужно явно прописывать proxy_set_header Upgrade и Connection "upgrade". Как выбрать между Traefik и Nginx Proxy Manager для такой связки, разобрано в статье Traefik или Nginx Proxy Manager: что выбрать для сервера.
Бэкап потоков и проекта
Все данные Node-RED — потоки (flows.json), учетные данные узлов (flows_cred.json), установленные пакеты палитры (package.json в /data) — лежат в томе nodered_data. Бэкап сводится к архивированию этого тома:
docker run --rm \
-v nodered_data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/nodered-backup-$(date +%F).tar.gz -C /data .
Восстановление — обратная операция: остановить контейнер, распаковать архив в новый том, поднять контейнер заново.
Более удобный вариант для тех, кто активно правит потоки — включить NODE_RED_ENABLE_PROJECTS=true (он уже стоит в примере compose-файла выше) и подключить том /data/projects к git-репозиторию. Тогда каждое сохранение в редакторе можно коммитить, а история изменений потоков видна в обычном git log. Это особенно полезно, если над автоматизациями работает не один человек.
Общие принципы бэкапа контейнеров и томов на VPS, включая ротацию и офсайт-хранение, — в статье Бэкап и восстановление Home Assistant: подход к томам Docker там идентичный, меняется только путь.
Ресурсы сервера и типичные проблемы
Сам Node-RED легковесный — 200-400 МБ RAM в простое хватает с запасом, нагрузку создают не потоки, а узлы: function-ноды с тяжелой обработкой JSON, узлы для работы с изображениями/видео, длинные цепочки HTTP-запросов с параллельным выполнением. Для домашней автоматизации на десяток-другой устройств достаточно 1 vCPU / 1-2 ГБ RAM, если на том же сервере крутится еще и Home Assistant с базой данных — закладывайте 2 vCPU / 4 ГБ.
Частые проблемы и решения:
| Симптом | Причина | Решение | |
|---|---|---|---|
| После рестарта контейнера потоки не сохранились | Volume не примонтирован или указан не тот путь | Проверить `docker inspect nodered \ | grep -A5 Mounts, том должен указывать на /data` |
Узел exec не находит команду хоста (например, ping) | Команды хоста недоступны внутри контейнера | Либо ставить утилиту через кастомный Dockerfile поверх базового образа, либо использовать network_mode: host для сетевых операций | |
| MQTT-узел не подключается к брокеру на хосте | Обращение к localhost внутри контейнера — это сам контейнер, не хост | Указать IP хоста в локальной сети или имя контейнера брокера, если он в той же docker-сети | |
Установленные через Palette Manager узлы пропадают после docker compose pull | Пакеты ставились в /data/node_modules, но том не был подключен | Проверить, что nodered_data смонтирован в /data до установки узлов, а не после | |
| Высокая загрузка CPU без активных автоматизаций | Флоу с циклом (нода отправляет сообщение сама себе без задержки) | Добавить delay-ноду или лимит частоты в проблемном потоке, искать через вкладку debug |
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли запустить Node-RED и Home Assistant в одном docker-compose.yml?
Да, это частая практика для домашнего сервера — оба сервиса описываются как отдельные services в одном файле и попадают в одну общую сеть, тогда обращение по имени контейнера работает без дополнительной настройки.
Нужен ли отдельный MQTT-брокер, если я не использую Zigbee/Z-Wave устройства?
Нет, MQTT-узел в Node-RED — это просто один из способов обмена сообщениями. Если все взаимодействие идет через Home Assistant Companion или HTTP-запросы, брокер не обязателен.
Как обновить Node-RED без потери потоков?
docker compose pull && docker compose up -d — том с данными не трогается при обновлении образа, потоки, credentials и установленные узлы сохраняются. Перед мажорным обновлением версии все же стоит сделать архив тома, как описано выше.
Можно ли запустить несколько независимых инстансов Node-RED на одном сервере?
Да — второй сервис в том же compose-файле с другим container_name, отдельным томом (nodered2_data) и другим портом или Host-правилом в Traefik. Это удобно, если нужно разделить, например, потоки умного дома и потоки для внешней интеграции.
Что делать, если забыл пароль администратора?
Отредактировать settings.js в томе /data, сгенерировав новый bcrypt-хеш командой из раздела про пароль, и перезапустить контейнер — доступ к файлу тома есть у любого, кто может зайти на сервер через SSH.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →