My personal nut-server on a Raspberry Pi 4
50K+
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.
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
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:
| Tag | Example | Meaning |
|---|---|---|
X.Y.Z-R | 2.8.0-7 | Exact Debian package version. Pin this for a specific server version. |
X.Y.Z | 2.8.0 | Upstream version; moves to the newest Debian revision of that version. |
YYYY.MM | 2026.07 | Immutable stamp of one monthly build (base-OS patch level). |
latest | Newest build. | |
*-latest | amd64-latest | Legacy 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).
| Variable | Description | Default |
|---|---|---|
NAME | UPS identifier | ups |
DRIVER | NUT driver | usbhid-ups |
PORT | Device port | auto |
POLLFREQ | Polling interval (s) | 5 |
DESC | UPS description | UPS |
USERSSTRING | NUT users block (see below) | # (none) |
TZ | Timezone | Etc/UTC |
lsusb
# Bus 001 Device 005: ID 051d:0002 American Power Conversion UPS
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.
USERSSTRING='[monuser]
password = secret
upsmon slave'
Compatible drivers: see the NUT Hardware Compatibility List.
Common alternatives to usbhid-ups: blazer_usb, nutdrv_qx.
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).blazer_usb or
nutdrv_qx.⭐ Star • 🐛 Issue • 🔧 PR • ☕ https://paypal.me/ErosNardi
Content type
Image
Digest
sha256:744cd2eee…
Size
39.7 MB
Last updated
25 days ago
docker pull nardo86/nut-server