Zum Inhalt

USV-Überwachung mit NUT per Docker: Unterbrechungsfreie Stromversorgung smart im Heimnetz überwachen

Veröffentlicht am 4. Oktober 2026 · Geschätzte Lesezeit: 8 Minuten

Eine eigene USV (Unterbrechungsfreie Stromversorgung) schützt Server und Netzwerk vor plötzlichen Stromausfällen. Mit NUT (Network UPS Tools) im Docker-Container wird die USV im ganzen Heimnetz sichtbar: Andere Geräte – NAS, Homeserver, Proxmox – können sich bei Stromausfall sauber herunterfahren, bevor die Batterie leer ist. Die Einrichtung dauert etwa 45 bis 60 Minuten.[1]

Voraussetzungen

  • Ein Linux-Server mit Docker und Docker Compose
  • Eine USV per USB angeschlossen (z. B. APC, Eaton, CyberPower, Tripp Lite)
  • Terminal-Zugriff mit sudo-Rechten
  • Ein freier TCP-Port 3493 im Heimnetz

1. USV am Host identifizieren

Prüfe zuerst, ob der Server die USV per USB erkennt:

lsusb

Eine mögliche Ausgabe sieht zum Beispiel so aus:

Bus 001 Device 004: ID 051d:0002 American Power Conversion Back-UPS RS 1600SI

Notiere die Bus-Nummer (001). Die Device-Nummer kann nach einem Neustart wechseln, die Bus-Nummer bleibt meist gleich. Deine USV muss in der Liste erscheinen – erscheint sie nicht, prüfe das USB-Kabel und einen anderen USB-Port.

2. NUT-Treiber ermitteln

NUT bringt viele Treiber mit. Der Befehl nut-scanner zeigt, welcher Treiber zu deiner USV passt. Installiere NUT kurz auf dem Host (nur für die Erkennung, der spätere Dienst läuft im Container):

sudo apt install nut
sudo nut-scanner -U

Die Ausgabe zeigt die nötigen Treiber-Details:

Scanning USB bus.
[nutdev1]
    driver = "nutdrv_qx"
    port = "auto"
    vendorid = "0665"
    productid = "5161"
    product = "UPS"
    bus = "001"

Die meisten modernen USVs werden entweder vom Treiber usbhid-ups (APC, Eaton) oder nutdrv_qx (viele günstigere Modelle) unterstützt.[3] Notiere dir driver, vendorid und productid – du brauchst sie in Schritt 4.

Treiber nicht gefunden?

Die vollständige Kompatibilitätsliste findest du auf der NUT-HCL-Seite.[3] Dort siehst du, welcher Treiber für dein USV-Modell nötig ist. Falls usbhid-ups oder nutdrv_qx nicht funktionieren, probiere blazer_usb oder schau in der HCL nach dem passenden Subdriver.

3. Projektordner anlegen

Erstelle einen eigenen Ordner für die NUT-Konfiguration:

mkdir -p ~/docker/nut
cd ~/docker/nut

Hier liegen später die Compose-Datei, das Passwort-Secret und optionale eigene Konfigurationsdateien.

4. Passwort-Secret anlegen

NUT benötigt einen API-Benutzer mit Passwort für die Kommunikation zwischen den Komponenten. Lege eine geheime Datei an:

echo '<dein-sicheres-passwort>' > nut-upsd-password
chmod 600 nut-upsd-password

Ersetze <dein-sicheres-passwort> durch ein starkes, zufälliges Passwort. Der Befehl chmod 600 stellt sicher, dass nur der Besitzer die Datei lesen kann.[2]

5. Docker-Compose-Datei erstellen

Erstelle die Datei compose.yaml im Verzeichnis ~/docker/nut:

services:
  nut-upsd:
    image: instantlinux/nut-upsd:latest
    container_name: nut-upsd
    privileged: true
    devices:
      - /dev/bus/usb:/dev/bus/usb
    ports:
      - "3493:3493"
    environment:
      - API_USER=upsmon
      - API_PASSWORD_FILE=/run/secrets/nut-upsd-password
      - DRIVER=nutdrv_qx
      - NAME=meine-usv
      - DESCRIPTION=USV im Serverrack
      - SERVER=primary
      - VENDORID=0665
    secrets:
      - nut-upsd-password
    restart: unless-stopped

secrets:
  nut-upsd-password:
    file: ./nut-upsd-password

Bedeutung der wichtigsten Einstellungen:

Abschnitt Erklärung
privileged: true Nötig für den Zugriff auf USB-Geräte des Hosts[2]
/dev/bus/usb Mountet das gesamte USB-Verzeichnis – so bleiben die Pfade auch nach einem Reboot gültig
3493:3493 NUT-Standard-Port (links: Host-Port, rechts: Container-Port)
API_USER=upsmon Der API-Benutzername; die Clients melden sich später mit diesem Namen an
API_PASSWORD_FILE= Pfad zum Secret mit dem Passwort (sicherer als API_PASSWORD als Umgebungsvariable)[2]
DRIVER=nutdrv_qx Ersetze durch den Treiber aus Schritt 2 (usbhid-ups oder nutdrv_qx)[2]
NAME=meine-usv Eindeutiger Name der USV – wird später für den Zugriff benötigt (z. B. upsc meine-usv@localhost)
DESCRIPTION=USV im Serverrack Frei wählbare Beschreibung
SERVER=primary Dieser Container ist der primäre NUT-Server
VENDORID=0665 Ersetze durch den Wert aus Schritt 2 (siehe vendorid im nut-scanner-Ergebnis)[2]
secrets: Docker-Compose Secrets – das Passwort wird sicher aus der Datei geladen, nicht als Klartext in der Compose-Datei

USB-Pfad nach Neustart

Wer das komplette USB-Verzeichnis (/dev/bus/usb) mountet, ist auf der sicheren Seite. Alternativ kannst du den exakten Bus-Pfad angeben (/dev/bus/usb/001:/dev/bus/usb/001), aber der kann nach einem Kernel-Update oder Neustart springen. Im Zweifel den gesamten USB-Bus durchreichen.

6. Container starten

Starte den NUT-Container:

docker compose up -d

Prüfe den Status:

docker compose ps

Erwartete Ausgabe:

NAME       IMAGE                           ...  STATUS
nut-upsd   instantlinux/nut-upsd:latest    ...  Up 30 seconds

7. USV-Status lokal abfragen

Frage die USV-Daten direkt vom laufenden Container ab:

docker exec nut-upsd upsc meine-usv@localhost

Eine erfolgreiche Ausgabe zeigt zum Beispiel:

battery.charge: 100
battery.voltage: 13.2
device.model: Back-UPS RS 1600SI
driver.name: usbhid-ups
ups.load: 12
ups.status: OL
ups.realpower.nominal: 300

Die wichtigsten Status-Werte:

Wert Bedeutung
OL On Line – Die USV läuft am Stromnetz (Normalzustand)
OB On Battery – Stromausfall, die USV läuft auf Batterie
LB Low Battery – Batterie fast leer, kritischer Zustand
CHRG Charging – Batterie wird geladen

8. Zugriff aus dem Heimnetz testen

Von einem anderen Rechner im selben Netz kannst du die USV-Daten ebenfalls abfragen – so weißt du, dass der NUT-Server korrekt arbeitet:

upsc meine-usv@<deine-server-ip>

Ersetze <deine-server-ip> durch die IP-Adresse deines Docker-Servers. Ist upsc auf dem Client nicht installiert, hilft ein kurzer Test mit telnet oder nc:

telnet <deine-server-ip> 3493

Bei erfolgreicher Verbindung erscheint eine leere Eingabe oder die Meldung Connected to .... Schließe die Verbindung mit ++ctrl+c++.

9. Client einrichten (NAS, zweiter Server)

Damit sich andere Geräte automatisch herunterfahren, wenn die USV auf Batterie läuft, richtest du auf jedem Client den NUT-Monitor ein.

Installiere auf dem Client (Debian/Ubuntu):

sudo apt install nut-client

Erstelle oder bearbeite die Datei /etc/nut/nut.conf:

MODE=netclient

Bearbeite /etc/nut/upsmon.conf und füge diese Zeile hinzu:

MONITOR meine-usv@<deine-server-ip> 1 upsmon <dein-sicheres-passwort> secondary

Ersetze <deine-server-ip> durch die IP deines NUT-Servers und <dein-sicheres-passwort> durch das Passwort aus Schritt 5.

Starte den Monitor-Dienst:

sudo systemctl restart nut-monitor
sudo systemctl enable nut-monitor

Prüfe den Status:

sudo systemctl status nut-monitor

Client testen

Führe auf dem Client upsc meine-usv@<deine-server-ip> aus. Erscheinen die gleichen Werte wie auf dem Server, ist die Verbindung hergestellt.

10. Home Assistant einbinden

Willst du die USV-Daten in Home Assistant sehen, füge in der configuration.yaml hinzu:

sensor:
  - platform: nut
    host: <deine-server-ip>
    port: 3493
    name: USV
    username: upsmon
    password: <dein-sicheres-passwort>
    resources:
      - ups.status
      - ups.load
      - battery.charge
      - battery.runtime
      - battery.voltage
      - input.voltage

Nach einem Neustart von Home Assistant erscheinen die Sensoren (z. B. sensor.usv_battery_charge, sensor.usv_ups_status).

11. Backup und Rückweg

Sichere die gesamte NUT-Konfiguration regelmäßig:

cd ~/docker
tar czf nut-backup-$(date +%F).tar.gz nut/

Zum vollständigen Entfernen:

cd ~/docker/nut
docker compose down -v
rm -rf ~/docker/nut

Deine USV ist danach wieder nur lokal am Server angeschlossen – der NUT-Dienst läuft nicht mehr.

12. Aktualisieren

Halte das Docker-Image aktuell:

cd ~/docker/nut
docker compose pull
docker compose up -d

Nach dem Update laufen die Clients und Home Assistant ohne Änderung weiter.

13. Typische Fehler

  • lsusb zeigt keine USV. Das USB-Kabel ist locker oder die USV wird vom Host nicht erkannt. Probiere einen anderen USB-Port und prüfe das Kabel.
  • Container startet nicht. Fehlende Secrets-Datei oder falsche Pfadangabe. Prüfe, ob nut-upsd-password existiert und chmod 600 gesetzt ist. Kontrolliere die Logs mit docker compose logs.
  • upsc meldet „Connection failure“. Der Container läuft nicht, die Firewall blockiert Port 3493, oder die IP-Adresse stimmt nicht. Prüfe docker compose ps und sudo ufw status.
  • Falsche Bus-Nummer nach Neustart. Der Bus-Pfad im devices:-Mapping kann nach einem Kernel-Update springen. Der Hinweis: /dev/bus/usb (ganzes USB-Verzeichnis) statt einer festen Nummer mounten.
  • upsc zeigt keine Werte oder „Data stale“. Der Treiber (DRIVER) passt nicht zur USV. Wechsle zu usbhid-ups oder nutdrv_qx mit passendem VENDORID. Prüfe die Logs mit docker compose logs.
  • Port 3493 blockiert. Öffne die Firewall auf dem Docker-Host: sudo ufw allow 3493.

14. Sicherheitshinweise

NUT nicht direkt ins Internet stellen

NUT verwendet standardmäßig kein TLS. Der Port 3493 gehört nur ins vertrauenswürdige Heimnetz. Für den Zugriff von unterwegs nutzt du ein VPN (WireGuard, Tailscale).

  • Das Passwort in der Secret-Datei sollte einmalig und stark sein. Die Datei mit chmod 600 schützen.
  • Der Container läuft mit privileged: true – das ist für den USB-Zugriff nötig, aber ein kompromittierter Container hätte weitreichende Rechte. Setze ihn daher nur auf Servern ein, denen du vertraust.
  • NUT unterstützt ab Version 2.8.5 STARTTLS, die Docker-Images aktivieren es aber oft nicht standardmäßig. Fürs Heimnetz ist der Verzicht auf TLS vertretbar, wer TLS nutzen will, installiert NUT nativ.[1]

15. Quellen

Fertig

NUT läuft auf deinem Server und macht deine USV im Heimnetz sichtbar. Prüfe diese Punkte:

  • docker compose ps zeigt nut-upsd mit Status Up
  • docker exec nut-upsd upsc meine-usv@localhost zeigt die aktuellen USV-Daten
  • upsc meine-usv@<deine-server-ip> von einem anderen Rechner liefert die gleichen Werte
  • In Home Assistant erscheint sensor.usv_battery_charge

Simuliere den Stromausfall: Ziehe das Netzkabel der USV und beobachte, wie der Status von OL auf OB wechselt. Nach dem Wiedereinstecken sollte OL erscheinen.