Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Gartenautomation
  • Mikrocontroller
    • Arduino
    • ESP32 & Co.
    • Calliope Mini
    • Raspberry Pi & Pico
  • Solo Mining
  • Deutsch
  • English
Menu

Node-RED mit Docker – SQLite Datenbank anbinden und erste Abfragen

Veröffentlicht am 30. März 202630. März 2026 von Stefan Draeger

Wie du Node-RED in einem Docker-Container startest, habe ich dir bereits im Beitrag „Node-RED mit Docker installieren – Schritt für Schritt“ gezeigt.
Nun gehen wir einen Schritt weiter und binden eine Datenbank an, damit wir die im Flow gesammelten Daten dauerhaft speichern können.

Node-RED mit Docker – SQLite Datenbank anbinden und erste Abfragen
Dieses Video auf YouTube ansehen.

Gerade im Zusammenspiel node-red sqlite docker ist SQLite eine ideale Lösung für den Einstieg.
Der große Vorteil: SQLite benötigt keinen eigenen Server, sondern speichert alle Daten in einer einzigen Datei. Diese Datei können wir einfach in einem eingebundenen Docker-Volume ablegen und behalten unsere Daten auch nach einem Neustart des Containers.

Damit eignet sich SQLite perfekt für:

  • Logging von Sensordaten
  • Zwischenspeichern von API-Daten
  • einfache IoT-Projekte (z. B. mit Shelly oder ESP32)

In diesem Beitrag zeige ich dir Schritt für Schritt, wie du eine SQLite-Datenbank in Node-RED einbindest und erste SQL-Abfragen ausführst.

Inhaltsverzeichnis

  • Warum SQLite für Node-RED ideal ist
  • SQLite Nodes in Node-RED installieren
  • Datenbank im Container anlegen und einbinden
    • Setzen der Rechte für die Datenbank
    • Rechte im Container anpassen
    • Warum ist das notwendig?
  • Datum und Uhrzeit per SQL abfragen
    • Minimaler Test-Flow
      • Inject Node konfigurieren
      • SQLite Node konfigurieren
      • Debug Node
  • Daten in SQLite speichern
    • Function Node zum Erzeugen von Zufallsdaten
  • Einfaches Dashboard für die Tabelle personen
    • Flow zum speichern von Daten in der Datenbank
    • Flow zum lesen der Daten aus der Datenbank und anzeigen in einer Tabelle
    • Flow zum löschen aller Datensätze
  • Fazit & Ausblick

Warum SQLite für Node-RED ideal ist

Wenn du mit Node-RED arbeitest, möchtest du Daten häufig nicht nur kurzfristig im Flow verarbeiten, sondern auch dauerhaft speichern. Genau hier kommt eine Datenbank ins Spiel.

Für den Einstieg ist SQLite besonders gut geeignet, da sie im Vergleich zu klassischen Datenbanksystemen wie MySQL oder PostgreSQL deutlich einfacher aufgebaut ist.

Der größte Vorteil: SQLite benötigt keinen eigenen Server.
Alle Daten werden in einer einzigen Datei gespeichert, die direkt im Dateisystem liegt. In unserem Fall bedeutet das, dass wir die Datenbank einfach im Docker-Volume von Node-RED ablegen können – zum Beispiel im Verzeichnis /data.

SQLite Datenbank im Docker Volume abgelegt
SQLite Datenbank im Docker Volume abgelegt

Das bringt mehrere Vorteile mit sich:

  • Einfache Einrichtung
    Keine zusätzliche Installation oder Konfiguration eines Datenbankservers notwendig
  • Perfekt für Docker geeignet
    Die Datenbank ist nur eine Datei und kann problemlos über ein Volume persistent gespeichert werden
  • Ideal für kleine bis mittlere Projekte
    z. B. Logging von Sensordaten, API-Daten oder einfache Auswertungen
  • Geringer Ressourcenverbrauch
    SQLite ist sehr leichtgewichtig und läuft problemlos auch auf einem Raspberry Pi

Gerade im Zusammenspiel Node-RED SQLite Docker ergibt sich damit eine sehr schlanke und gleichzeitig leistungsfähige Lösung, um Daten aus deinen Flows zu speichern und später weiterzuverarbeiten.

Für größere Projekte mit vielen gleichzeitigen Zugriffen oder komplexen Abfragen kann später immer noch auf Systeme wie MySQL oder PostgreSQL gewechselt werden. Für den Einstieg und viele IoT-Anwendungen ist SQLite jedoch mehr als ausreichend.

SQLite Nodes in Node-RED installieren

Damit wir eine SQLite-Datenbank in Node-RED verwenden können, benötigen wir zunächst die passenden Nodes. Diese lassen sich ganz einfach über die integrierte Paketverwaltung nachinstallieren.

Öffne dazu im Node-RED Editor das Menü oben rechts und gehe auf:

👉 Menü → Palette verwalten → Reiter „Installieren“

Im Suchfeld gibst du anschließend sqlite ein. In der Ergebnisliste erscheint das Paket:

👉 node-red-node-sqlite

Node-RED - Installieren der SQLite Node - Step 1
Node-RED - Installieren der SQLite Node - Step 2

Dieses Paket stellt dir die notwendigen Nodes zur Verfügung, um SQL-Abfragen direkt innerhalb deiner Flows auszuführen.

Klicke auf Installieren und warte einen Moment, bis die Installation abgeschlossen ist. In der Regel ist kein Neustart erforderlich – die neuen Nodes stehen sofort im linken Bereich (Palette) zur Verfügung.

Nach der erfolgreichen Installation findest du die SQLite Node unter den Storage-Nodes und kannst sie per Drag & Drop in deinen Flow ziehen.

installierte SQLite Node in Node-RED

Datenbank im Container anlegen und einbinden

Für dieses Beispiel gehen wir bewusst einen einfachen und direkten Weg, um schnell eine funktionierende SQLite-Datenbank zu erhalten.

Da unser Node-RED Container ein Docker-Volume verwendet, liegt dieses auf dem Host-System im Verzeichnis:

/var/lib/docker/volumes/<volume_name>/_data/

In meinem Fall lautet der Pfad:

sudo -i
cd /var/lib/docker/volumes/stefan_node_red_data/_data/

Hier können wir direkt unsere Datenbankdatei anlegen:

sqlite3 datenbank.db

Anschließend erstellen wir direkt eine erste Tabelle:

CREATE TABLE IF NOT EXISTS personen (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    vorname TEXT NOT NULL,
    nachname TEXT NOT NULL,
    strasse TEXT,
    plz TEXT,
    ort TEXT
);

Danach verlassen wir die SQLite-Konsole mit:

.quit

Hinweis: Dieser Ansatz ist bewusst einfach gehalten und eignet sich besonders gut für Tests und kleinere Projekte. Alternativ könnte man auch direkt im Container arbeiten oder ein eigenes Docker-Image erstellen – für unseren Einstieg ist das jedoch nicht zwingend notwendig.

Setzen der Rechte für die Datenbank

Wenn du die SQLite-Datenbank manuell im Docker-Volume angelegt hast, kann es passieren, dass Node-RED später nicht in die Datenbank schreiben kann.

Typische Fehlermeldung:

SQLITE_READONLY: attempt to write a readonly database

Die Ursache liegt in den Dateirechten:
Die Datenbankdatei wird häufig als root erstellt, während Node-RED im Container mit einem anderen Benutzer läuft.

Rechte im Container anpassen

Um das Problem zu beheben, wechseln wir zunächst als root in den Container:

docker exec -it --user root nodered bash
Zugriff auf den Docker Container via bash mit root Rechte
Zugriff auf den Docker Container via bash mit root Rechte

Dann setzen wir die richtigen Rechte für die Datenbankdatei und das Verzeichnis:

cd /data
chown 1000:1000 datenbank.db
chown 1000:1000 .
chmod 664 datenbank.db
chmod 755 .
exit

In meinem Fall läuft der Node-RED Docker-Container mit dem „normalen“ Benutzer, der beim Einrichten des Linux-Systems erstellt wurde. Dieser Benutzer hat in der Regel die UID 1000.

👉 Daher setzen wir den Besitzer der Datei und des Verzeichnisses ebenfalls auf diese UID, sodass Node-RED Schreibzugriff auf die SQLite-Datenbank erhält.

Warum ist das notwendig?

SQLite benötigt Schreibrechte auf:

  • die Datenbankdatei selbst
  • das Verzeichnis, in dem die Datei liegt

Nur wenn beide korrekt gesetzt sind, kann Node-RED Daten speichern.

Datum und Uhrzeit per SQL abfragen

Nachdem wir nun die SQLite Node installiert und unsere Datenbank angelegt haben, erstellen wir im nächsten Schritt unseren ersten einfachen Flow in Node-RED.

Ziel ist es, eine erste SQL-Abfrage auszuführen und das Ergebnis im Debug-Tab anzuzeigen.

Minimaler Test-Flow

Für diesen ersten Test benötigen wir lediglich drei Nodes:

  • Inject Node → startet den Flow und enthält das SQL-Statement
  • SQLite Node → führt die Abfrage aus
  • Debug Node → zeigt das Ergebnis an
Node-RED Flow zum lesen eines Zeitstempels aus einer SQLite Datenbank
Node-RED Flow zum lesen eines Zeitstempels aus einer SQLite Datenbank

Inject Node konfigurieren

In der Inject Node hinterlegen wir direkt unser SQL-Statement im Feld msg.topic:

SELECT date('now');

👉 Wichtig: Die SQLite Node erwartet das SQL-Statement im Feld msg.topic.

SQLite Node konfigurieren

Damit die SQLite Node auf unsere Datenbank zugreifen kann, muss diese einmalig konfiguriert werden.

  1. SQLite Node öffnen
  2. Auf das Plus-Symbol (+) neben „Datenbank“ klicken
  3. Pfad zur Datenbank eintragen: /data/datenbank.db
  4. Mit „Hinzufügen“ und anschließend „Fertig“ bestätigen
SQLite Node - Datenbank anbinden - Step 1
SQLite Node - Datenbank anbinden - Step 2
SQLite Node - Datenbank anbinden - Step 3

👉 Die SQLite Node ist nun einsatzbereit und verarbeitet SQL-Statements aus msg.topic.

Debug Node

Die Debug Node muss nicht weiter konfiguriert werden.

Standardmäßig lauscht sie bereits auf das Feld:

msg.payload

👉 Genau dort liefert die SQLite Node auch das Ergebnis der SQL-Abfrage.

Daten in SQLite speichern

Nachdem wir erfolgreich eine erste SQL-Abfrage ausgeführt haben, wollen wir nun Daten in unsere Tabelle personen schreiben.

Dazu erstellen wir einen einfachen Flow mit einer zusätzlichen Function Node welche uns zufallsdaten erzeugt.

Node-RED Flow zum speichern von Daten in der SQLite Datenbank
Node-RED Flow zum speichern von Daten in der SQLite Datenbank

Function Node zum Erzeugen von Zufallsdaten

Die Daten für die Tabelle personen könnten natürlich auch aus einem Formular im Dashboard stammen.
Der Einfachheit halber verwenden wir hier jedoch eine Function Node, die aus einer vordefinierten Liste zufällige Werte auswählt und daraus einen Datensatz erzeugt.

const vornamen = ["Max", "Anna", "Peter", "Laura", "Stefan", "Julia", "Thomas", "Sophie"];
const nachnamen = ["Mustermann", "Müller", "Schmidt", "Meier", "Schulz", "Becker", "Hoffmann", "Klein"];
const strassen = ["Hauptstraße 1", "Bahnhofstraße 12", "Gartenweg 7", "Bergstraße 22", "Mühlenweg 5"];
const plzOrte = [
    { plz: "38364", ort: "Schöningen" },
    { plz: "38100", ort: "Braunschweig" },
    { plz: "38440", ort: "Wolfsburg" },
    { plz: "38820", ort: "Halberstadt" },
    { plz: "39104", ort: "Magdeburg" }
];

function zufallEintrag(arr) {
    return arr[Math.floor(Math.random() * arr.length)];
}

const vorname = zufallEintrag(vornamen);
const nachname = zufallEintrag(nachnamen);
const strasse = zufallEintrag(strassen);
const plzOrt = zufallEintrag(plzOrte);

msg.topic = `
    INSERT INTO personen (vorname, nachname, strasse, plz, ort)
    VALUES ('${vorname}', '${nachname}', '${strasse}', '${plzOrt.plz}', '${plzOrt.ort}');
`;

return msg;

Dieser Ansatz ist bewusst simpel gehalten und eignet sich hervorragend für erste Tests.
Für produktive Anwendungen – etwa mit Benutzereingaben oder externen Datenquellen – stößt diese Methode jedoch schnell an ihre Grenzen.

zufällige Daten erzeugt mit der Function Node
zufällige Daten erzeugt mit der Function Node

👉 Für unseren Einstieg ist sie jedoch vollkommen ausreichend, um die Funktionalität der Datenbank zu testen und erste Datensätze zu erzeugen.

selektieren von Datensätze über SQLite3
selektieren von Datensätze über SQLite3

Einfaches Dashboard für die Tabelle personen

Nachdem wir nun die Tabelle personen in der Datenbank angelegt haben, erstellen wir als Nächstes ein einfaches Dashboard, über das neue Datensätze bequem erfasst werden können.

Node-RED - einfaches Dashboard für die Tabelle personen
Node-RED – einfaches Dashboard für die Tabelle personen

Das Ziel ist dabei bewusst einfach gehalten:
Wir möchten neue Personen über eine kleine Eingabemaske anlegen und die Daten direkt in unserer SQLite-Datenbank speichern.

Für dieses erste Beispiel konzentrieren wir uns ausschließlich auf das Hinzufügen neuer Einträge.
Das Bearbeiten oder Löschen vorhandener Datensätze würde den Flow deutlich komplexer machen und wird deshalb in einem separaten Beitrag behandelt.

Node-RED Flows für das Dashboard der Tabelle personen
Node-RED Flows für das Dashboard der Tabelle personen
Node-RED Flows für das Dashboard der Tabelle personenHerunterladen

Flow zum speichern von Daten in der Datenbank

Der Flow zum Speichern der Daten in der Datenbank wird einmalig gestartet und stellt über das Dashboard ein Eingabeformular bereit. Die eingegebenen Daten werden anschließend in einer Function-Node zu einem INSERT INTO-Statement verarbeitet und danach in die Datenbank geschrieben.

Flow zum speichern von Daten in der Datenbank
Flow zum speichern von Daten in der Datenbank

Das Eingabeformular lässt sich über die Form-Node recht einfach konfigurieren. Hier definieren wir die einzelnen Felder mit Namen, die beim Absenden an die Function-Node übergeben und dort weiterverarbeitet werden.

konfiguration des Fomulars
konfiguration des Fomulars
let vorname = msg.payload.vorname;
let nachname = msg.payload.nachname;
let strasse = msg.payload.strasse;
let postleitzahl = msg.payload.plz;
let ort = msg.payload.ort;

msg.topic = `
INSERT INTO personen (vorname, nachname, strasse, plz, ort)
VALUES ('${vorname}', '${nachname}', '${strasse}', '${postleitzahl}', '${ort}');
`;

return msg;

Die Formulardaten befinden sich im Feld msg.payload und können dort direkt ausgelesen werden.
In diesem einfachen Beispiel verzichten wir bewusst auf eine Validierung oder Prüfung auf doppelte Einträge. Die Werte werden lediglich entnommen und im INSERT INTO-Statement an die entsprechenden Stellen eingesetzt.

Am Ende des Flows wird der Prozess zum Aktualisieren der Daten angestoßen, sodass die Tabelle den neu hinzugefügten Datensatz direkt anzeigt.

Aufrufen des Flows zum aktualisieren der Tabelle
Aufrufen des Flows zum aktualisieren der Tabelle

Flow zum lesen der Daten aus der Datenbank und anzeigen in einer Tabelle

Der Flow zum Aktualisieren der Tabelle mit den Daten aus der Tabelle personen verfügt über zwei Eingänge: Zum einen wird er automatisch gestartet, zum anderen kann er von anderen Flows aus angestoßen werden.

Im Anschluss folgt eine Function-Node, die das SELECT-Statement erstellt und über msg.topic an die SQLite-Node übergibt.

Die Function-Node schreibt lediglich das SELECT-Statement in das Feld msg.topic.
Alternativ könnte man dieses auch über eine Inject-Node realisieren. Allerdings würde das Statement dann fehlen, wenn der Flow von einem anderen Flow aus gestartet wird.

msg.topic = "SELECT * FROM personen;";
return msg;
Konfiguration der Table Node
Konfiguration der Table Node

In der Konfiguration der Table Node legen wir zunächst fest das neue Wert die vorhandenen ersetzen, sowie die Spalten NICHT automatisch erkannt werden sollen.
Daraus folgt jedoch das wir im unteren Bereich dann die Spalten manuell anlegen müssen. Hier können wir uns aus einer zuvor angelegten Debug Node der Felder bedienen welche wir anlegen müssen.

Ausgabe des SELECT Statements

Flow zum löschen aller Datensätze

Da wir derzeit lediglich nur mit Testdaten arbeiten reicht ein knopf zum löschen aller Daten. Dabei ist zu beachten das der Index der Tabelle nicht zurück gesetzt wird d.h. dieser wird erstmal noch fortgeführt.

Flow zum löschen aller Daten aus der Tabelle personen via Button aus dem Dashboard
Flow zum löschen aller Daten aus der Tabelle personen via Button aus dem Dashboard

Das Statement wird wie zuvor auch von einer Function Node bereitgestellt.

msg.topic = "DELETE FROM personen;";
return msg;
Aufrufen des Flows zum aktualisieren der Tabelle
Aufrufen des Flows zum aktualisieren der Tabelle

Am Ende starten wir wieder den Flow zum laden der Daten der Tabelle wobei hier einfach die Tabelle geleert wird.

Fazit & Ausblick

Mit diesem einfachen Dashboard haben wir die Grundlage geschaffen, neue Personen komfortabel in unserer Tabelle personen zu erfassen.

Gerade im Zusammenspiel Node-RED SQLite Docker zeigt sich, wie schnell sich eine funktionierende Oberfläche zur Datenerfassung umsetzen lässt – ganz ohne aufwendige Webentwicklung.

Damit steht bereits ein kleiner, aber sehr praktischer Baustein für eigene Anwendungen bereit. In weiteren Ausbaustufen könnte man das Dashboard später noch um Bearbeiten, Löschen oder zusätzliche Funktionen erweitern.

Außerdem bietet sich die Tabelle als ideale Basis für weitere Praxisbeispiele an. So könnte man in einem späteren Beitrag zum Beispiel zeigen, wie sich diese Daten nutzen lassen, um einen einfachen Newsletter-Versand umzusetzen.

Letzte Aktualisierung am: 30. März 2026

Foto von Stefan Draeger
Über den Autor

Stefan Draeger — Entwickler & Tech-Blogger

Ich zeige praxisnah, wie du Projekte mit Arduino, ESP32 und Smarthome-Komponenten umsetzt – Schritt für Schritt, mit Code und Schaltplänen.

Mehr Artikel von Stefan →

Schreibe einen Kommentar Antwort abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • QR-Code Generator
  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen
Tel.: 015565432686
E-Mail: info@draeger-it.blog

Folge mir auf

link zu Fabook
link zu LinkedIn
link zu YouTube
link zu TikTok
link zu Pinterest
link zu Instagram
  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2026 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
  • Optionen verwalten
  • Dienste verwalten
  • Verwalten von {vendor_count}-Lieferanten
  • Lese mehr über diese Zwecke
Einstellungen anzeigen
  • {title}
  • {title}
  • {title}