Sign inSign up

nardo86/nut-server

By nardo86

•Updated 25 days ago

My personal nut-server on a Raspberry Pi 4

Image
0

50K+

nardo86/nut-server repository overview

⁠NUT Server Docker Container

Containerized Network UPS Tools⁠ server on Debian, for monitoring USB UPS devices over the network (port 3493). Multi-arch: linux/amd64, linux/arm64, linux/arm/v7. Tested on Raspberry Pi 4.

Status: community-maintained, no active testing. Functional and stable for the author's setup (Raspberry Pi 4 + APC USB UPS). Issues and PRs welcome.

⁠Quick Start

services:
  nut-server:
    image: nardo86/nut-server:latest
    container_name: nut-server
    ports:
      - "3493:3493"
    # Bind /dev/bus/usb as a volume (not `devices:`) so the UPS stays visible
    # after a USB re-enumeration — see "USB access" below
    volumes:
      - "/dev/bus/usb:/dev/bus/usb"
    device_cgroup_rules:
      - "c 189:* rwm"
    environment:
      NAME: home-ups
      DESC: Home APC Back-UPS ES 700
      POLLFREQ: 5
      TZ: Europe/Rome
    restart: unless-stopped

Or as a one-shot docker run:

docker run -d --name nut-server -p 3493:3493 \
  -v /dev/bus/usb:/dev/bus/usb \
  --device-cgroup-rule='c 189:* rwm' \
  --restart unless-stopped \
  nardo86/nut-server:latest

⁠Tags & versions

The NUT server comes from Debian's nut-server package, so its version is whatever Debian stable currently ships (bookworm → upstream 2.8.0). Images are tagged along two independent axes — which NUT version and which build:

TagExampleMeaning
X.Y.Z-R2.8.0-7Exact Debian package version. Pin this for a specific server version.
X.Y.Z2.8.0Upstream version; moves to the newest Debian revision of that version.
YYYY.MM2026.07Immutable stamp of one monthly build (base-OS patch level).
latestNewest build.
*-latestamd64-latestLegacy 2021-era aliases, kept in sync with latest.

The image is rebuilt monthly to pick up Debian security patches; the NUT version itself only changes when Debian does (at the next stable release). The packaged version is recorded in NUT_VERSION⁠ and in the image's OCI labels, so you can check any tag without guessing from the tag name:

# From the image metadata (no need to run it):
docker inspect --format '{{ index .Config.Labels "org.networkupstools.version" }}' \
  nardo86/nut-server:2.8.0
# Straight from the server binary:
docker run --rm --entrypoint upsd nardo86/nut-server:2.8.0 -V

For the record: tags 2025.06–2025.10 were the previous bullseye-based line (NUT 2.7.4-13); 2026.05 onward are bookworm (NUT 2.8.0-7).

⁠Configuration

VariableDescriptionDefault
NAMEUPS identifierups
DRIVERNUT driverusbhid-ups
PORTDevice portauto
POLLFREQPolling interval (s)5
DESCUPS descriptionUPS
USERSSTRINGNUT users block (see below)# (none)
TZTimezoneEtc/UTC
⁠Find your UPS
lsusb
# Bus 001 Device 005: ID 051d:0002 American Power Conversion UPS
⁠USB access

When a UPS drops off the bus and reconnects (flaky cable, self-reset), the kernel re-enumerates it under a new device node (.../001/005 → .../001/006). Mappings made with --device/devices: are snapshotted at container creation, so after a re-enumeration the container keeps talking to the dead node and the driver reports stale data until you recreate it.

Binding the whole /dev/bus/usb tree as a volume plus a device cgroup rule (c 189:* rwm — major 189 is USB) keeps newly enumerated nodes visible inside the container, as shown in the Quick Start. Pinning a single node with --device=/dev/bus/usb/001/005 still works if your UPS never re-enumerates, but is fragile.

⁠Synology / remote monitoring users
USERSSTRING='[monuser]
  password = secret
  upsmon slave'

Compatible drivers: see the NUT Hardware Compatibility List⁠. Common alternatives to usbhid-ups: blazer_usb, nutdrv_qx.

⁠Troubleshooting

  • Device not found: check lsusb on the host, verify the USB mapping, ensure the container has access (no --user overrides, USB cgroup allowed).
  • Data for UPS [...] is stale - check driver: the UPS re-enumerated on the USB bus and the container lost it — see "USB access" above for the re-enumeration-proof mapping. The built-in healthcheck marks the container unhealthy in this state; Docker does not restart unhealthy containers by itself, so pair it with something that does (e.g. autoheal⁠ with an autoheal=true label on this container).
  • Connection refused on 3493: verify port mapping and host firewall.
  • Driver errors in logs: wrong driver for your model — try blazer_usb or nutdrv_qx.

⁠Notes

  • NUT version tracks whatever Debian stable ships (currently bookworm, NUT 2.8.0), not the upstream latest — see Tags & versions⁠ for how to pin or inspect a specific version.
  • Built with help from Claude (Anthropic). Review the configuration before production use. No warranty.
  • Image: https://hub.docker.com/r/nardo86/nut-server⁠

⁠Support

⭐ Star • 🐛 Issue • 🔧 PR • ☕ https://paypal.me/ErosNardi⁠

Tag summary

Content type

Image

Digest

sha256:744cd2eee…

Size

39.7 MB

Last updated

25 days ago

docker pull nardo86/nut-server