Skip to content

Nardo86/nut-docker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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:

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.062025.10 were the previous bullseye-based line (NUT 2.7.4-13); 2026.05 onward are bookworm (NUT 2.8.0-7).

Configuration

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

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

About

My personal nut-server on a Raspberry Pi 4

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages