Building a Smart Holiday Home Hub with Docker, Home Assistant, and Node-RED on Raspberry Pi 5

At our holiday home — a quiet place we visit just once or twice a year — I wanted to know exactly what’s happening there, even when we’re not around. Call it freak-control if you will, but when you have a heating system running through the winter and the power tends to drop every now and then, staying informed gives a certain peace of mind.

So I decided to build a small but powerful automation hub based on a Raspberry Pi 5, running Docker, Home Assistant, Node-RED, and an MQTT broker (Mosquitto).
The idea is simple: all sensors (Govee, Tuya, Smart Life, and others) feed into one unified web interface where I can monitor temperature, humidity, power state, and even camera feeds — no matter where I am.

This post walks through the entire setup — from installing Docker on the Raspberry Pi to deploying Home Assistant, Node-RED, and Mosquitto in containers. By the end, you’ll have a self-contained, remotely accessible automation hub that’s reliable, restart-safe, and ready to expand with new devices or automations.

Now, you might be thinking: “Alright, but if the power goes out, what exactly are you monitoring?”
That’s a fair question — and we’ll get there soon, when we talk about backup power, network resiliency, and remote notifications.
But first, let’s focus on building the main system — the heart of the automation setup that ties everything together.

Section 1 – Installing Docker and Docker Compose on Raspberry Pi 5

Before we start deploying anything, we need a solid foundation — Docker.
Running Home Assistant, Node-RED, and Mosquitto inside Docker containers gives us isolation, easy backups, and simple updates. It also means the Raspberry Pi can recover cleanly after a power failure without any manual intervention.

The good news is that Docker works beautifully on the Raspberry Pi 5 — fast storage, enough RAM, and a 64-bit OS make it feel like a mini server.

Let’s set it up.

Step 1 – Update your system

It’s always a good idea to make sure your system is up to date before installing new components:

sudo apt update && sudo apt upgrade -y
sudo apt install curl git -y

This ensures all system packages and dependencies are current.

Step 2 – Install Docker (Official Script)

The simplest and most reliable way to install Docker on a Raspberry Pi is through the official Docker installation script.
It automatically detects your platform, installs all necessary components, and configures Docker to start on boot.

Run:

curl -fsSL https://get.docker.com | sudo sh

Once the installation completes, Docker will be up and running as a service (dockerd).

You can check its status with:

sudo systemctl status docker

If you see “active (running)”, you’re good to go.

Step 3 – Add your user to the Docker group

By default, Docker commands require root privileges.
To avoid typing sudo every time, add your user to the docker group:

sudo usermod -aG docker $USER

Then log out and back in (or reboot) for the changes to take effect.

You can verify this by running:

groups

You should see docker listed among your groups.

Step 4 – Verify the installation

Check that Docker works:

docker --version
docker info

You should see something like:

Docker version 28.5.2, build ecc6942

To confirm it can actually run containers, try this:

docker run hello-world

If you get a message starting with “Hello from Docker!”, everything’s working.

Step 5 – Verify Docker Compose (v2)

Docker Compose v2 is now built directly into the Docker CLI — no need to install it separately.

Test it with:

docker compose version

You should see output similar to:

Docker Compose version v2.40.3

If this works, you’re ready to orchestrate multiple containers using a single docker-compose.yml file.

Step 6 – Enable Docker on startup

To make sure Docker starts automatically on boot:

sudo systemctl enable docker
sudo systemctl start docker

That’s it — Docker is now set up to start automatically and manage containers even after a power outage or reboot.

Step 7 – Quick test with Compose

Before we move to the main stack (Home Assistant, Node-RED, Mosquitto), let’s make sure docker compose actually works.

Create a test directory:

mkdir ~/compose-test && cd ~/compose-test

Create a simple docker-compose.yml file:

version: "3"
services:
  hello:
    image: hello-world

Then run:

docker compose up

You should see the familiar “Hello from Docker!” message again — this time launched via Compose.

That’s all we need for the Docker base layer.

Section 2 – Deploying Home Assistant, Node-RED and Mosquitto with Docker Compose

With Docker up and running, we can now set up the actual automation stack.
The goal here is to run three containers side by side, each with a clear purpose:

  • Home Assistant – the central brain of the system, where all sensors and smart devices are integrated.
  • Node-RED – a visual tool for building automation flows and dashboards.
  • Mosquitto (MQTT broker) – the message bus that connects Home Assistant and Node-RED with all MQTT-capable devices.

By running all three inside Docker, each service stays isolated, easy to restart, and safe from system updates.

Step 1 – Create a project directory

We’ll keep everything in a single folder so it’s easy to back up later:

mkdir ~/homeauto
cd ~/homeauto

Inside this folder, Docker will store configuration and persistent data for each container.

Step 2 – Create the Docker Compose file

Create a new file named docker-compose.yml:

nano docker-compose.yml

Paste the following content:

services:
  homeassistant:
    image: ghcr.io/home-assistant/home-assistant:stable
    container_name: homeassistant
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./homeassistant:/config
    environment:
      - TZ=Europe/Bucharest

  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

  nodered:
    image: nodered/node-red:latest
    container_name: nodered
    restart: unless-stopped
    ports:
      - "1880:1880"
    environment:
      - TZ=Europe/Bucharest
    volumes:
      - ./nodered/data:/data

Save and exit (Ctrl+O, Enter, Ctrl+X).

This file defines our three services, their ports, and where they’ll store persistent data.

Step 3 – Configure Mosquitto (MQTT broker)

Create the necessary directories and configuration files for Mosquitto:

mkdir -p mosquitto/config mosquitto/data mosquitto/log
nano mosquitto/config/mosquitto.conf

Paste this minimal configuration:

listener 1883
allow_anonymous false
password_file /mosquitto/config/passwd

Then create an MQTT user and password:

docker run --rm -it -v $(pwd)/mosquitto/config:/mosquitto/config eclipse-mosquitto mosquitto_passwd -c /mosquitto/config/passwd homeauto

You’ll be asked for a password — remember it; we’ll use it later in Home Assistant and Node-RED.

Step 4 – Start the containers

Now bring the entire stack to life:

docker compose up -d

Docker will download the images and start all services in the background.

You can check their status with:

docker compose ps

If Node-RED fails to start (permission denied)

After running docker compose up -d, you might notice that Home Assistant and Mosquitto start correctly, but Node-RED keeps restarting or won’t open on port 1880.
If you run docker compose ps, it may show something like:

nodered   Restarting (1) ...

and docker logs nodered might include an error such as:

Error: EACCES: permission denied, copyfile ... '/data/settings.js'

This happens because the Node-RED container doesn’t have permission to write into the local nodered/data directory.

To fix it, simply adjust the file ownership on your Raspberry Pi:

cd ~/homeauto
sudo chown -R 1000:1000 nodered
docker compose restart nodered

Node-RED runs as user ID 1000 inside the container (the same as a normal Linux user), so giving it ownership of its data directory allows it to write configuration files properly.

After this, you should see:

Server now running at http://127.0.0.1:1880/

and be able to open Node-RED at:

http://<your_pi_ip>:1880

Step 5 – Access the web interfaces

Once everything is up, you can reach each service through your browser:

  • Home Assistant: http://<your_pi_ip>:8123
  • Node-RED: http://<your_pi_ip>:1880
  • Mosquitto: (no web interface — just the MQTT broker on port 1883)

The first startup may take a few minutes, especially for Home Assistant.

Step 6 – Initial setup in Home Assistant

When you first open Home Assistant, it will guide you through creating an admin account.
After that:

  1. Go to Settings → Devices & Services → Add Integration
  2. Add:
    • Tuya (for Smart Life / Tuya devices)
    • MQTT (connect to your local Mosquitto broker)
    • Optionally later: HACS (Home Assistant Community Store) for Govee and community plugins

To connect to MQTT, use these values:

  • Broker address: localhost
  • Port: 1883
  • Username: homeauto
  • Password: (the one you created earlier)

Once connected, Home Assistant can both publish and subscribe to MQTT topics.

Section 3 – Integrating Node-RED with Home Assistant

Now that both Home Assistant and Node-RED are up and running, it’s time to make them talk to each other.
Node-RED will handle the logic and visual flow of your automations, while Home Assistant remains the central hub that holds all devices, sensors, and entities.

To make this connection, we’ll link Node-RED directly to Home Assistant’s API using a secure access token.
This allows Node-RED to read entity states, listen for events, and trigger automations — all in real time.

Step 1 – Create an Access Token in Home Assistant

To allow Node-RED to communicate with Home Assistant, we need to create a secure access token (an API key).
Here’s how:

  1. Open Home Assistant in your browser: http://<your_pi_ip>8123
  2. In the bottom-left corner, click on your username (this opens your Profile page).
  3. Scroll down to the section called Long-Lived Access Tokens.
  4. Click Create Token
  5. Give it a descriptive name, for example: Node-RED connection
  6. Click OK — Home Assistant will generate a long string of characters.
    Important: Copy it immediately and save it somewhere safe.
    Once you close the dialog, you won’t be able to see it again.

Step 2 – Add the Home Assistant Integration in Node-RED

  1. Open Node-RED in your browser: http://<your_pi_ip>1880
  2. Go to Menu → Manage palette → Install, and search for:
    node-red-contrib-home-assistant-websocket

    Install it — this package adds the Home Assistant nodes to Node-RED, allowing direct interaction with entities and services.

    While you’re here, it’s also a good idea to install:
    node-red-dashboard

    This package lets you build custom web dashboards with charts, gauges, buttons, and controls — perfect for monitoring your sensors or controlling devices from a simple browser interface at: http://<your_pi_ip>1880/ui
  3. After installation, drag an events: state node onto the workspace (you’ll find it under the home assistant category in the left sidebar).
  4. Double-click the node to open its configuration.
    In the Server field, click the plus icon to add a new server connection.
  5. Fill in the details:
    Base URL: http://<your_pi_ip>:8123

    (Home Assistant runs in host network mode, while Node-RED runs in a bridge network — so you must use the Raspberry Pi’s IP address)

    Access Token:
    (paste the token you created earlier in Home Assistant)
  6. Click Add, then Done.
  7. Click Deploy in the top right corner to save and apply the changes.

Step 3 – Test the Connection

Let’s verify that Node-RED and Home Assistant can communicate properly.

  1. In Node-RED, open the events: state node you already added in the previous step.
  2. In the node’s settings, make sure you select a real entity from Home Assistant — for example: sun.sun
    or any existing sensor such as:
    sensor.temperature_livingroom
    If you leave this field empty, you’ll see a “ConfigError: An entity is required” message in the Debug panel.
  3. Connect the node to a debug node and click Deploy.
  4. When the selected entity changes state (for example, the temperature updates or the sun goes below the horizon), you’ll see a message appear in Node-RED’s Debug tab.

If the node shows “running” and you can select entities directly from Home Assistant, it means the integration is working perfectly.

What Happens Under the Hood

Home Assistant provides a WebSocket API that streams entity updates in real time.
Node-RED uses this connection to:

  • Listen to entity state changes (like sensors, lights, switches, motion detectors)
  • Trigger automations when events occur
  • Call services (for example: turn on lights, adjust heating, send notifications)

This setup gives you the best of both worlds:

  • Home Assistant remains your central platform for devices, sensors, and integrations.
  • Node-RED becomes your flexible logic layer — a place to build complex automations visually, without writing YAML code.

Wrap-Up

At this point, the foundation of the system is complete.
Home Assistant and Node-RED are connected, exchanging data in real time.
You can now see entities from Home Assistant directly inside Node-RED and start building your first automation flows.

This setup is the backbone of everything that follows — a modular environment where each component does exactly what it’s best at:
Home Assistant manages and integrates devices, Node-RED handles logic and visualization, and Mosquitto takes care of all MQTT communication in the background.

In the next post, we’ll move from theory to practice — connecting real sensors and smart devices (Tuya, Govee, and Smart Life), publishing their data via MQTT, and creating dashboards to monitor what’s happening at the house, even when we’re miles away.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top