Coordinated Homelab UPS Shutdown Guide
Ubuntu, Docker Compose, and Synology NAS Integration with NUT
This guide documents a real-world implementation of automated UPS shutdown handling using Network UPS Tools (NUT) in a Docker-based homelab environment.
Rather than focusing on abstract UPS concepts, this document provides:
- Real configuration examples
- Proven shutdown sequencing
- Docker integration guidance
- Synology NAS coordination
- Troubleshooting procedures
- Lessons learned from real deployments
Who Is This For?
This guide is aimed at:
- Homelab administrators running Ubuntu servers, Intel NUCs, mini PCs, or micro-clusters
- Docker users who need stateful containers to shut down cleanly
- Self-hosters using consumer or white-label UPS hardware
- Anyone integrating:
- Ubuntu
- Docker Compose
- Synology NAS systems
- NUT UPS monitoring
Goals
The objective is a coordinated, low-risk shutdown process during utility power failure.
The desired sequence is:
- Detect UPS power loss on a primary Ubuntu node
- Notify all networked NUT clients
- Gracefully stop Docker containers
- Safely shut down operating systems
- Command the UPS to cut output power
- Automatically restore power when utility power returns
Environment
The following architecture was used successfully during testing:
| Component | Description |
|---|---|
| NUT Master | Ubuntu Mini PC / Intel NUC connected to UPS via USB |
| NUT Clients | Synology NAS units and additional Ubuntu hosts |
| Workloads | Docker Compose stacks |
| Stateful Apps | PostgreSQL, MariaDB, Redis, Immich, Paperless-ngx, Home Assistant |
| UPS Type | USB-connected UPS using serial-over-USB chipset |
Recommended Architecture
[ AC Utility Power Grid ]
│
▼
┌─────────────────┐
│ UPS Hardware │◄──────────────┐
└────────┬────────┘ │
│ USB Cable │
▼ │
┌────────────────────┐ │
│ Ubuntu NUT Master │ │ 4. Cut Output
│ (Mini PC Host) │ │
└──────┬──────┬──────┘ │
│ │ │
1. Signal │ │ 2. Signal │
Shutdown │ │ Shutdown │
▼ ▼ │
┌────────────┐ ┌─────────────────────┐ │
│ Synology │ │ Docker Containers │ │
│ NUT Client │ │ (Graceful Stop 30s+)│ │
└────────────┘ └─────────┬───────────┘ │
│ │
│ 3. OS Halt │
▼ │
┌──────────────────┐ │
│ Ubuntu Host Halt │────┘
└──────────────────┘
Shutdown Sequence
When utility power fails, the system proceeds through a strict hierarchy to reduce the risk of corruption.
1. Grid Disconnect
The UPS switches to battery mode and alerts the Ubuntu NUT Master through USB.
2. Client Alerting
The NUT Master broadcasts shutdown notifications to all connected clients, including Synology NAS systems.
3. Container Teardown
Docker containers receive shutdown events and begin graceful termination.
Applications with databases or persistent storage should be given extended shutdown windows.
4. Operating System Shutdown
Ubuntu and Synology systems flush filesystem buffers and halt cleanly.
5. UPS Power Cut
The NUT Master sends a final killpower command to the UPS.
This cuts output power to:
- Preserve battery capacity
- Allow clean auto-recovery
- Prevent UPS lockup states
Basic NUT Configuration
1. Identifying the Correct Driver
Many budget UPS devices expose themselves as serial-over-USB hardware rather than standard USB HID UPS devices.
If usbhid-ups fails, inspect the device:
lsusb
or:
dmesg | grep -i usb
For hardware reporting:
- Vendor ID:
0665 - Product ID:
5161 - Manufacturer:
INNO TECH
the correct driver is often:
nutdrv_qx
2. /etc/nut/ups.conf
Example configuration:
[ups]
driver = nutdrv_qx
port = auto
vendorid = 0665
productid = 5161
desc = "Homelab Primary UPS"
offdelay = 30
ondelay = 180
Important Parameters
| Parameter | Purpose |
|---|---|
offdelay = 30 |
Wait 30 seconds before cutting UPS output |
ondelay = 180 |
Delay power restoration after utility returns |
Why Use ondelay?
A delay helps protect systems from:
- Grid instability
- Rapid power cycling
- Brownout oscillations
3. /etc/nut/upsmon.conf
Ensure the shutdown flag file is configured correctly:
POWERDOWNFLAG /etc/killpower
This path is critical.
Avoid:
- Broken quotation marks
- Trailing characters
- Incorrect paths
Docker Shutdown Handling
By default, Docker only allows containers 10 seconds to stop before sending SIGKILL.
For databases and indexing systems, this can be dangerous.
1. Configure Graceful Shutdown Periods
Example docker-compose.yml configuration:
services:
database:
image: postgres:16-alpine
container_name: postgres_db
restart: unless-stopped
volumes:
- ./db_data:/var/lib/postgresql/data
stop_grace_period: 45s
paperless:
image: paperlessngx/paperless-ngx
container_name: paperless_main
restart: unless-stopped
stop_grace_period: 60s
2. Apply Runtime Changes
Editing docker-compose.yml does not automatically update running containers.
Recreate containers after modifying shutdown timers.
Option A — Force Recreation
docker compose up -d --force-recreate
Option B — Full Restart
docker compose down
docker compose up -d
Synology NAS Configuration
To integrate a Synology NAS into the shutdown process:
- Open:
text
Control Panel → Hardware & Power → UPS
- Enable:
text
Enable UPS Support
- Set UPS Type:
text
Synology UPS Server Client
-
Enter the IP address of the Ubuntu NUT Master
-
Under shutdown timing:
text
Same as Server
!!! tip "Why 'Same as Server' Matters"
Avoid setting a fixed timer such as "2 minutes".
Fixed values can conflict with the master node's shutdown logic.
Selecting **Same as Server** allows DSM to respond directly to the NUT Forced Shutdown (FSD) signal and safely unmount storage pools immediately.
Testing Shutdowns
1. Software-Level Simulation
You can safely test the shutdown sequence without unplugging the UPS.
Run:
sudo upsmon -c fsd
This simulates a forced shutdown event across the NUT infrastructure.
What This Tests
- Client notifications
- Synology responses
- Docker shutdown timing
- Host shutdown order
2. Real Hardware Test
After software tests succeed:
- Ensure all systems are fully running
- Unplug the UPS from wall power
- Observe logs on:
- Ubuntu master
- Synology clients
- Additional hosts
- Allow battery thresholds to trigger shutdown
- Confirm:
- UPS cuts power output
- Systems restart properly after utility restoration
Common Problems & Troubleshooting
Issue 1 — Stale PID Files
Symptoms
- Drivers refuse to start
- Duplicate driver errors
- Socket binding failures
Resolution
# Stop services
sudo systemctl stop nut-server nut-monitor
# Kill lingering processes
sudo pkill -9 nut
sudo pkill -9 upsdrvctl
# Clear runtime state
sudo rm -rf /run/nut/*
sudo rm -rf /var/run/nut/*
# Restart drivers
sudo upsdrvctl start
Issue 2 — "Driver Not Connected"
This error often indicates a driver-level issue rather than a full NUT failure.
Diagnostic Procedure
# Standard startup
sudo upsdrvctl start
# Manual debug mode
sudo /lib/nut/nutdrv_qx -a ups -DD
This exposes:
- Descriptor mismatches
- USB communication issues
- Unsupported chipset behavior
Issue 3 — Systems Remain Powered Off
If systems shut down correctly but never restart after utility power returns:
BIOS Configuration Required
In BIOS or firmware settings:
Restore on AC Power Loss → Power On
or:
Restore on AC Power Loss → Last State
Avoid:
Remain Off
Lessons Learned
Driver Mapping Matters
Do not assume all USB UPS hardware uses usbhid-ups.
Many consumer UPS systems rely on serial-over-USB emulation and require:
nutdrv_qx
Simulated Tests Are Not Enough
Running:
sudo upsmon -c fsd
is excellent for validating network coordination, but it does not confirm:
- UPS recovery behavior
- Battery cut-off handling
- Auto-restart functionality
A real-world power-loss test is still required.
Sequence Matters More Than Speed
Attempting to shut everything down simultaneously increases the risk of corruption.
A safer hierarchy is:
Clients
↓
Containers
↓
Master Host
↓
UPS Output Cut
Order and timing are more important than shutting down quickly.
Final Notes
A properly configured NUT environment can dramatically reduce the risk of:
- Filesystem corruption
- Database inconsistency
- Docker container damage
- Improper NAS shutdowns
The key is disciplined sequencing, realistic testing, and explicit shutdown timing across every layer of the stack.