Add NUT Web GUI app

This commit is contained in:
okxlin
2026-08-01 02:41:23 +08:00
parent 6ab05890ac
commit 4d6802fdfb
18 changed files with 567 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
PANEL_APP_PORT_HTTP=9000
UPSD_ADDRESS=nut.example.com
UPSD_PORT=3493
UPSD_USERNAME=
UPSD_PASSWORD=
UPSD_TLS_MODE=disable
APP_CONFIG_DIR=./data
CONTAINER_NAME=1Panel-localnut-webgui
+123
View File
@@ -0,0 +1,123 @@
additionalProperties:
formFields:
- default: 9000
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: HTTP Port
labelZh: HTTP 端口
label:
en: HTTP Port
zh: HTTP 端口
zh-Hant: HTTP 埠
ja: HTTP ポート
ko: HTTP 포트
ru: HTTP-порт
ms: Port HTTP
pt-br: Porta HTTP
required: true
rule: paramPort
type: number
- default: ""
edit: true
envKey: UPSD_ADDRESS
labelEn: NUT Server Address
labelZh: NUT 服务器地址
label:
en: NUT Server Address
zh: NUT 服务器地址
zh-Hant: NUT 伺服器位址
ja: NUT サーバーアドレス
ko: NUT 서버 주소
ru: Адрес сервера NUT
ms: Alamat pelayan NUT
pt-br: Endereco do servidor NUT
required: true
type: text
- default: 3493
edit: true
envKey: UPSD_PORT
labelEn: NUT Server Port
labelZh: NUT 服务器端口
label:
en: NUT Server Port
zh: NUT 服务器端口
zh-Hant: NUT 伺服器埠
ja: NUT サーバーポート
ko: NUT 서버 포트
ru: Порт сервера NUT
ms: Port pelayan NUT
pt-br: Porta do servidor NUT
required: true
rule: paramPort
type: number
- default: ""
edit: true
envKey: UPSD_USERNAME
labelEn: NUT Username
labelZh: NUT 用户名
label:
en: NUT Username
zh: NUT 用户名
zh-Hant: NUT 使用者名稱
ja: NUT ユーザー名
ko: NUT 사용자 이름
ru: Имя пользователя NUT
ms: Nama pengguna NUT
pt-br: Usuario NUT
required: false
type: text
- default: ""
edit: true
envKey: UPSD_PASSWORD
labelEn: NUT Password
labelZh: NUT 密码
label:
en: NUT Password
zh: NUT 密码
zh-Hant: NUT 密碼
ja: NUT パスワード
ko: NUT 비밀번호
ru: Пароль NUT
ms: Kata laluan NUT
pt-br: Senha NUT
required: false
type: password
- default: disable
edit: true
envKey: UPSD_TLS_MODE
labelEn: NUT TLS Mode
labelZh: NUT TLS 模式
label:
en: NUT TLS Mode
zh: NUT TLS 模式
zh-Hant: NUT TLS 模式
ja: NUT TLS モード
ko: NUT TLS 모드
ru: Режим TLS NUT
ms: Mod TLS NUT
pt-br: Modo TLS NUT
required: true
type: select
values:
- label: disable
value: disable
- label: strict
value: strict
- label: skip
value: skip
- default: ./data
edit: true
envKey: APP_CONFIG_DIR
labelEn: Configuration Directory
labelZh: 配置目录
label:
en: Configuration Directory
zh: 配置目录
zh-Hant: 設定目錄
ja: 設定ディレクトリ
ko: 설정 디렉터리
ru: Каталог конфигурации
ms: Direktori konfigurasi
pt-br: Diretorio de configuracao
required: true
type: text
+36
View File
@@ -0,0 +1,36 @@
services:
nut-webgui:
image: "ghcr.io/superioone/nut_webgui:0.10.2"
container_name: ${CONTAINER_NAME}
restart: unless-stopped
networks:
- 1panel-network
ports:
- "${PANEL_APP_PORT_HTTP}:9000"
environment:
- UPSD_ADDR=${UPSD_ADDRESS}
- UPSD_PORT=${UPSD_PORT}
- UPSD_USER=${UPSD_USERNAME}
- UPSD_PASS=${UPSD_PASSWORD}
- UPSD_TLS=${UPSD_TLS_MODE}
- LISTEN=0.0.0.0
- PORT=9000
- UID=1000
- GID=1000
- LOG_LEVEL=info
volumes:
- "${APP_CONFIG_DIR}:/etc/nut_webgui"
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD-SHELL", "wget -q -O - http://127.0.0.1:9000/probes/health >/dev/null || exit 1"]
interval: 30s
timeout: 5s
retries: 5
start_period: 15s
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
fail() {
printf '%s\n' "$1" >&2
exit 1
}
read_env_value() {
local key="$1"
local value=""
value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)"
case "$value" in
\"*\") value="${value#\"}"; value="${value%\"}" ;;
\'*\') value="${value#\'}"; value="${value%\'}" ;;
esac
printf '%s\n' "$value"
}
effective_value() {
local key="$1"
if [[ -v "$key" ]]; then
printf '%s\n' "${!key}"
else
read_env_value "$key"
fi
}
[[ -f "$ENV_FILE" && ! -L "$ENV_FILE" ]] || fail "$ENV_FILE must be a regular file"
upsd_address="$(effective_value UPSD_ADDRESS)"
upsd_port="$(effective_value UPSD_PORT)"
tls_mode="$(effective_value UPSD_TLS_MODE)"
config_raw="$(effective_value APP_CONFIG_DIR)"
[[ -n "$upsd_address" && ! "$upsd_address" =~ [[:space:]/] ]] || fail "UPSD_ADDRESS must be a hostname or IP address"
[[ "$upsd_port" =~ ^[0-9]+$ ]] || fail "UPSD_PORT must be numeric"
((10#$upsd_port >= 1 && 10#$upsd_port <= 65535)) || fail "UPSD_PORT must be between 1 and 65535"
[[ "$tls_mode" == disable || "$tls_mode" == strict || "$tls_mode" == skip ]] || fail "UPSD_TLS_MODE must be disable, strict, or skip"
[[ -n "$config_raw" && ! "$config_raw" =~ [[:cntrl:]\`\$] ]] || fail "APP_CONFIG_DIR is invalid"
if [[ "$config_raw" == /* ]]; then
config_dir="$(realpath -m -- "$config_raw")"
else
config_dir="$(realpath -m -- "${ROOT_DIR}/${config_raw#./}")"
case "$config_dir" in
"${ROOT_DIR}"/*) ;;
*) fail "Relative APP_CONFIG_DIR must stay inside the application version directory" ;;
esac
fi
case "$config_dir" in
/ | /bin | /boot | /dev | /etc | /home | /lib | /lib64 | /opt | /proc | /root | /run | /sbin | /srv | /sys | /tmp | /usr | /var | /workspace)
fail "APP_CONFIG_DIR must be a dedicated subdirectory"
;;
esac
[[ ! -L "$config_dir" ]] || fail "APP_CONFIG_DIR must not be a symbolic link"
[[ ! -e "$config_dir" || -d "$config_dir" ]] || fail "APP_CONFIG_DIR must be a directory"
install -d -m 0775 -- "$config_dir"
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
# 1Panel owns persistent-data removal; the external NUT server is never changed.
exit 0
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
exec "${SCRIPT_DIR}/init.sh"
+35
View File
@@ -0,0 +1,35 @@
# NUT Web GUI
## 产品介绍
NUT Web GUI 是 Network UPS ToolsNUT)的轻量级 Web 界面,用于查看 UPS 状态、变量和事件。
## 主要功能
- 自动刷新 UPS 状态和变量
- 提供 JSON API、事件 WebSocket 和 OpenMetrics 指标
- 支持多个 NUT 服务器、TLS 和可选身份认证
- 可按 NUT 用户权限执行 `INSTCMD``SET VAR` 和 FSD 操作
## 访问说明
本应用不包含 NUT 服务端,也不直接访问 UPS 硬件。安装前需要准备一个从 1Panel 容器网络可访问的 `upsd` 地址和端口;如果 `upsd` 需要认证,请同时填写用户名和密码。
默认使用普通 Docker bridge 网络,不启用 host network。若 NUT 服务运行在同一宿主机,请填写宿主机在 Docker 网络中可访问的地址,不能使用容器内的 `127.0.0.1`
配置文件和会话签名密钥保存在版本目录的 `data` 目录。卸载时是否删除该目录由 1Panel 的数据删除选项决定。卸载不会向外部 NUT 服务发送控制命令。
## 安全说明
用于只读监控的 NUT 账号不应授予 `INSTCMD` 或 FSD 权限。仅在明确需要远程控制 UPS 时才提升外部 NUT 用户权限。
## Introduction
NUT Web GUI is a lightweight interface for viewing status, variables, and events from Network UPS Tools servers.
## Features
- Refreshes UPS status and variables automatically
- Provides JSON, WebSocket event, and OpenMetrics endpoints
- Connects to an external NUT server over an ordinary container network
- Persists configuration and the generated session-signing key
+22
View File
@@ -0,0 +1,22 @@
# NUT Web GUI
NUT Web GUI is a lightweight web interface for Network UPS Tools (NUT), displaying UPS status, variables, and events.
## Features
- Automatically refreshes UPS status and variables
- Provides a JSON API, event WebSocket, and OpenMetrics metrics
- Supports multiple NUT servers, TLS, and optional web authentication
- Can run `INSTCMD`, `SET VAR`, and FSD operations when the NUT user permits them
## Installation
This application does not include a NUT server and does not access UPS hardware directly. Before installation, provide an `upsd` address and port reachable from the 1Panel container network. Also provide a username and password when the `upsd` server requires authentication.
The package uses an ordinary Docker bridge network and does not enable host networking. If the NUT server runs on the same host, enter an address reachable from the Docker network; `127.0.0.1` inside this container refers to the container itself.
Configuration files and the session-signing key are stored in the version directory's `data` directory. Whether that directory is removed during uninstall is controlled by the 1Panel data-removal option. Uninstall does not send control commands to the external NUT server.
## Security
A NUT account used only for monitoring should not receive `INSTCMD` or FSD privileges. Grant control permissions to the external NUT user only when remote UPS control is explicitly required.
+34
View File
@@ -0,0 +1,34 @@
name: NUT Web GUI
tags:
- 实用工具
title: 用于监控 Network UPS Tools 设备的轻量级 Web 界面
description: 用于监控 Network UPS Tools 设备的轻量级 Web 界面
additionalProperties:
key: nut-webgui
name: NUT Web GUI
tags:
- Tool
shortDescZh: 用于监控 Network UPS Tools 设备的轻量级 Web 界面
shortDescEn: A lightweight web interface for monitoring Network UPS Tools devices
description:
en: A lightweight web interface for monitoring Network UPS Tools devices
zh: 用于监控 Network UPS Tools 设备的轻量级 Web 界面
zh-Hant: 用於監控 Network UPS Tools 裝置的輕量級 Web 介面
ja: Network UPS Tools デバイスを監視する軽量 Web インターフェース
ko: Network UPS Tools 장치를 모니터링하는 경량 웹 인터페이스
ru: Легкий веб-интерфейс для мониторинга устройств Network UPS Tools
ms: Antara muka web ringan untuk memantau peranti Network UPS Tools
pt-br: Interface web leve para monitorar dispositivos Network UPS Tools
type: tool
crossVersionUpdate: true
limit: 0
recommend: 0
website: https://github.com/SuperioOne/nut_webgui
github: https://github.com/SuperioOne/nut_webgui
document: https://github.com/SuperioOne/nut_webgui/blob/0f27202af128ade7bb93a951110cd61690a0599a/docs/examples/02_compose.md
architectures:
- amd64
- arm64
- riscv64
- arm/v6
- arm/v7
+8
View File
@@ -0,0 +1,8 @@
PANEL_APP_PORT_HTTP=9000
UPSD_ADDRESS=nut.example.com
UPSD_PORT=3493
UPSD_USERNAME=
UPSD_PASSWORD=
UPSD_TLS_MODE=disable
APP_CONFIG_DIR=./data
CONTAINER_NAME=1Panel-localnut-webgui
+123
View File
@@ -0,0 +1,123 @@
additionalProperties:
formFields:
- default: 9000
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: HTTP Port
labelZh: HTTP 端口
label:
en: HTTP Port
zh: HTTP 端口
zh-Hant: HTTP 埠
ja: HTTP ポート
ko: HTTP 포트
ru: HTTP-порт
ms: Port HTTP
pt-br: Porta HTTP
required: true
rule: paramPort
type: number
- default: ""
edit: true
envKey: UPSD_ADDRESS
labelEn: NUT Server Address
labelZh: NUT 服务器地址
label:
en: NUT Server Address
zh: NUT 服务器地址
zh-Hant: NUT 伺服器位址
ja: NUT サーバーアドレス
ko: NUT 서버 주소
ru: Адрес сервера NUT
ms: Alamat pelayan NUT
pt-br: Endereco do servidor NUT
required: true
type: text
- default: 3493
edit: true
envKey: UPSD_PORT
labelEn: NUT Server Port
labelZh: NUT 服务器端口
label:
en: NUT Server Port
zh: NUT 服务器端口
zh-Hant: NUT 伺服器埠
ja: NUT サーバーポート
ko: NUT 서버 포트
ru: Порт сервера NUT
ms: Port pelayan NUT
pt-br: Porta do servidor NUT
required: true
rule: paramPort
type: number
- default: ""
edit: true
envKey: UPSD_USERNAME
labelEn: NUT Username
labelZh: NUT 用户名
label:
en: NUT Username
zh: NUT 用户名
zh-Hant: NUT 使用者名稱
ja: NUT ユーザー名
ko: NUT 사용자 이름
ru: Имя пользователя NUT
ms: Nama pengguna NUT
pt-br: Usuario NUT
required: false
type: text
- default: ""
edit: true
envKey: UPSD_PASSWORD
labelEn: NUT Password
labelZh: NUT 密码
label:
en: NUT Password
zh: NUT 密码
zh-Hant: NUT 密碼
ja: NUT パスワード
ko: NUT 비밀번호
ru: Пароль NUT
ms: Kata laluan NUT
pt-br: Senha NUT
required: false
type: password
- default: disable
edit: true
envKey: UPSD_TLS_MODE
labelEn: NUT TLS Mode
labelZh: NUT TLS 模式
label:
en: NUT TLS Mode
zh: NUT TLS 模式
zh-Hant: NUT TLS 模式
ja: NUT TLS モード
ko: NUT TLS 모드
ru: Режим TLS NUT
ms: Mod TLS NUT
pt-br: Modo TLS NUT
required: true
type: select
values:
- label: disable
value: disable
- label: strict
value: strict
- label: skip
value: skip
- default: ./data
edit: true
envKey: APP_CONFIG_DIR
labelEn: Configuration Directory
labelZh: 配置目录
label:
en: Configuration Directory
zh: 配置目录
zh-Hant: 設定目錄
ja: 設定ディレクトリ
ko: 설정 디렉터리
ru: Каталог конфигурации
ms: Direktori konfigurasi
pt-br: Diretorio de configuracao
required: true
type: text
+36
View File
@@ -0,0 +1,36 @@
services:
nut-webgui:
image: "ghcr.io/superioone/nut_webgui:latest"
container_name: ${CONTAINER_NAME}
restart: unless-stopped
networks:
- 1panel-network
ports:
- "${PANEL_APP_PORT_HTTP}:9000"
environment:
- UPSD_ADDR=${UPSD_ADDRESS}
- UPSD_PORT=${UPSD_PORT}
- UPSD_USER=${UPSD_USERNAME}
- UPSD_PASS=${UPSD_PASSWORD}
- UPSD_TLS=${UPSD_TLS_MODE}
- LISTEN=0.0.0.0
- PORT=9000
- UID=1000
- GID=1000
- LOG_LEVEL=info
volumes:
- "${APP_CONFIG_DIR}:/etc/nut_webgui"
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD-SHELL", "wget -q -O - http://127.0.0.1:9000/probes/health >/dev/null || exit 1"]
interval: 30s
timeout: 5s
retries: 5
start_period: 15s
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
fail() {
printf '%s\n' "$1" >&2
exit 1
}
read_env_value() {
local key="$1"
local value=""
value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)"
case "$value" in
\"*\") value="${value#\"}"; value="${value%\"}" ;;
\'*\') value="${value#\'}"; value="${value%\'}" ;;
esac
printf '%s\n' "$value"
}
effective_value() {
local key="$1"
if [[ -v "$key" ]]; then
printf '%s\n' "${!key}"
else
read_env_value "$key"
fi
}
[[ -f "$ENV_FILE" && ! -L "$ENV_FILE" ]] || fail "$ENV_FILE must be a regular file"
upsd_address="$(effective_value UPSD_ADDRESS)"
upsd_port="$(effective_value UPSD_PORT)"
tls_mode="$(effective_value UPSD_TLS_MODE)"
config_raw="$(effective_value APP_CONFIG_DIR)"
[[ -n "$upsd_address" && ! "$upsd_address" =~ [[:space:]/] ]] || fail "UPSD_ADDRESS must be a hostname or IP address"
[[ "$upsd_port" =~ ^[0-9]+$ ]] || fail "UPSD_PORT must be numeric"
((10#$upsd_port >= 1 && 10#$upsd_port <= 65535)) || fail "UPSD_PORT must be between 1 and 65535"
[[ "$tls_mode" == disable || "$tls_mode" == strict || "$tls_mode" == skip ]] || fail "UPSD_TLS_MODE must be disable, strict, or skip"
[[ -n "$config_raw" && ! "$config_raw" =~ [[:cntrl:]\`\$] ]] || fail "APP_CONFIG_DIR is invalid"
if [[ "$config_raw" == /* ]]; then
config_dir="$(realpath -m -- "$config_raw")"
else
config_dir="$(realpath -m -- "${ROOT_DIR}/${config_raw#./}")"
case "$config_dir" in
"${ROOT_DIR}"/*) ;;
*) fail "Relative APP_CONFIG_DIR must stay inside the application version directory" ;;
esac
fi
case "$config_dir" in
/ | /bin | /boot | /dev | /etc | /home | /lib | /lib64 | /opt | /proc | /root | /run | /sbin | /srv | /sys | /tmp | /usr | /var | /workspace)
fail "APP_CONFIG_DIR must be a dedicated subdirectory"
;;
esac
[[ ! -L "$config_dir" ]] || fail "APP_CONFIG_DIR must not be a symbolic link"
[[ ! -e "$config_dir" || -d "$config_dir" ]] || fail "APP_CONFIG_DIR must be a directory"
install -d -m 0775 -- "$config_dir"
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
# 1Panel owns persistent-data removal; the external NUT server is never changed.
exit 0
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
exec "${SCRIPT_DIR}/init.sh"
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB