DEV Community

Miklos Halasz
Miklos Halasz

Posted on

Install NUT on RaspberryPi with AlmaLinux

I run one of my Raspberry Pi devices with AlmaLinux, installed on an external SSD connected through one of the USB 3 ports. This setup provides better performance and reliability compared to running from an SD card.

I followed Jeff Geerling’s guide to install the Network UPS Tools (NUT) server on the Pi to monitor my UPS. However, since AlmaLinux differs from Debian-based distributions, I needed to perform several additional steps to make everything work properly.


Tweak SELinux Flags

AlmaLinux enforces SELinux (Security-Enhanced Linux) by default, which provides a robust layer of system security. However, it also restricts services like httpd (installed automatically with nut-server) from performing certain network operations by default.

To allow the httpd service to connect to external ports, run:

sudo setsebool -P httpd_can_network_connect on
Enter fullscreen mode Exit fullscreen mode

This permanently sets the SELinux boolean that enables outbound network connections for httpd.


Configure the Firewall

AlmaLinux uses firewalld with a default deny-all policy, meaning all incoming connections are blocked unless explicitly allowed.

By default, the NUT web interface (served by httpd) listens on port 8808, so this port must be opened in the firewall:

sudo firewall-cmd --permanent --add-port=8808/tcp --zone=public
sudo firewall-cmd --reload
Enter fullscreen mode Exit fullscreen mode

After reloading, connections to port 8808/tcp will be permitted in the public zone.


Start the Driver

At this stage, the installation appeared to be successful — but the NUT server wouldn’t start. Checking the logs with journalctl revealed that the UPS driver hadn’t initialized.

I found a helpful Reddit thread explaining that the driver must start before the NUT server. That made sense, so I manually started the services in the correct order:

sudo upsdrvctl start
sudo systemctl start nut-server
Enter fullscreen mode Exit fullscreen mode

And voilà — everything started working:

$ upsdrvctl status
Network UPS Tools upsdrvctl - UPS driver controller 2.8.3 release
UPSNAME              UPSDRV     RUNNING PF_PID  S_RESPONSIVE    S_PID   S_STATUS
office-ups       usbhid-ups     RUNNING 702     RESPONSIVE      702     "OL"
Enter fullscreen mode Exit fullscreen mode

However — there’s always a “but.” 😄
After rebooting the Raspberry Pi, the services didn’t start automatically. Some additional configuration was needed to ensure the NUT driver and related services started on boot.


Enable Required Services on Boot

To ensure that the NUT driver and enumerator start automatically after a reboot, I enabled several related systemd services:

# Pull in NUT’s umbrella target (often required)
sudo systemctl enable --now nut.target

# Keep the looped enumerator running
sudo systemctl enable --now nut-driver-enumerator-daemon.service

# Optional but recommended: restart driver on ups.conf changes
sudo systemctl enable --now nut-driver-enumerator-daemon-activator.path
Enter fullscreen mode Exit fullscreen mode

Additionally, I modified the nut-driver-enumerator-daemon.service unit file to delay startup until the network was fully online and to ensure it used a safe start delay for the UPS driver:

[Unit]
Requires=network-online.target
After=network-online.target

[Service]
ConditionPathExists=/etc/ups/ups.conf
ExecStart=
ExecStart=/usr/libexec/nut-driver-enumerator.sh --daemon-after=60
Enter fullscreen mode Exit fullscreen mode

The --daemon-after=60 option ensures that the NUT driver starts 60 seconds after boot, giving the system and connected USB devices time to initialize properly.

After these adjustments, the NUT server started reliably on every boot, running cleanly and consistently.

Now my NAS and other connected systems are protected — if a power outage occurs, the NUT server communicates with the UPS and ensures all devices shut down gracefully.


Useful Links

Top comments (0)