ZMB Webui: Complete Project – Rebrand & Initial Clean Commit

ARCHITECTURE
============
Backend: FastAPI + uvicorn (port 8000)
  - JWT authentication with PAM system users
  - ZFS CLI wrapper with caching (30-60s TTL)
  - WebSocket pool status broadcaster (30s interval)
  - Services: auth, zfs_runner, file_manager, shares, identities, system_info
  - Routers: pools, datasets, snapshots, shares, identities, navigator, system

Frontend: Next.js 15 + TypeScript (static export)
  - Incremental Static Regeneration (ISR) for weak hardware
  - Type-safe API client (lib/api.ts)
  - Dark mode + custom Tailwind theme
  - Pages: Dashboard, Login, Snapshots, Datasets, Shares, etc.

DEPLOYMENT
==========
Test Target: 192.168.1.179:8090 (Debian LXC)
Production: 10.66.120.3:9090 (Raspberry Pi 4GB ARM64)
Updater: Automated Gitea-based deployment (update-test.sh, update-pi.sh)

FEATURES COMPLETED
==================
Phase 3a: Dashboard Quick Stats (System, CPU, Memory, Storage)
  - Real-time stats with color-coded progress bars
  - Responsive grid layout (mobile: 1, tablet: 2, desktop: 4 columns)
  - ISR-optimized for fast loads on weak hardware

REBRANDING
==========
Renamed throughout:
  - Project: 'ZFS Manager' → 'ZMB Webui'
  - Services: 'zfs-manager' → 'zmb-webui'
  - Systemd units: zfs-manager-backend → zmb-webui-backend
  - Configuration files and documentation

Co-Authored-By: Patrick <patrick@perlbach24.de>
This commit is contained in:
Claude Code
2026-04-22 00:26:23 +02:00
committed by Patrick
commit 6d74d874b6
104 changed files with 28836 additions and 0 deletions
+243
View File
@@ -0,0 +1,243 @@
#!/bin/bash
# ZMB Webui Deployment Script
# Unterstützt Frontend, Backend und Full-Deployment auf Remote-Host
# Usage: ./deploy.sh [--target HOST] [--backend-only|--frontend-only]
set -e
# Default values
TARGET="192.168.1.179"
DEPLOY_BACKEND=true
DEPLOY_FRONTEND=true
BACKEND_SERVICE="zmb-webui-backend"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--target)
TARGET="$2"
shift 2
;;
--backend-only)
DEPLOY_FRONTEND=false
shift
;;
--frontend-only)
DEPLOY_BACKEND=false
shift
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
exit 1
;;
esac
done
# Helper functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
check_prerequisites() {
log_info "Checking prerequisites..."
if ! command -v scp &> /dev/null; then
log_error "scp not found. Please install openssh-client"
exit 1
fi
if ! command -v ssh &> /dev/null; then
log_error "ssh not found. Please install openssh-client"
exit 1
fi
if ! command -v curl &> /dev/null; then
log_error "curl not found. Please install curl"
exit 1
fi
if [ "$DEPLOY_FRONTEND" = true ] && ! command -v npm &> /dev/null; then
log_error "npm not found. Please install Node.js/npm"
exit 1
fi
log_info "All prerequisites met"
}
check_ssh_connection() {
log_info "Testing SSH connection to $TARGET..."
if ! ssh -o ConnectTimeout=5 root@$TARGET "echo 'Connection OK'" > /dev/null 2>&1; then
log_error "Cannot connect to $TARGET via SSH"
exit 1
fi
log_info "SSH connection successful"
}
deploy_frontend() {
log_info "Building frontend..."
if [ ! -d "frontend" ]; then
log_error "frontend directory not found"
exit 1
fi
cd frontend
if [ ! -f "package.json" ]; then
log_error "package.json not found in frontend directory"
exit 1
fi
npm run build
if [ ! -d "out" ]; then
log_error "Frontend build failed - 'out' directory not created"
exit 1
fi
log_info "Frontend build successful"
cd ..
log_info "Uploading frontend to $TARGET..."
if ! scp -r frontend/out/* root@$TARGET:/opt/zmb-webui/backend/static/ 2>/dev/null; then
log_error "Failed to upload frontend files"
exit 1
fi
log_info "Frontend deployed successfully"
}
deploy_backend() {
log_info "Deploying backend services..."
if [ ! -d "backend/services" ]; then
log_error "backend/services directory not found"
exit 1
fi
if [ ! -f "backend/main.py" ]; then
log_error "backend/main.py not found"
exit 1
fi
log_info "Uploading backend services to $TARGET..."
if ! scp backend/services/*.py root@$TARGET:/opt/zmb-webui/backend/services/ 2>/dev/null; then
log_error "Failed to upload backend services"
exit 1
fi
log_info "Uploading main.py to $TARGET..."
if ! scp backend/main.py root@$TARGET:/opt/zmb-webui/backend/ 2>/dev/null; then
log_error "Failed to upload main.py"
exit 1
fi
log_info "Backend files uploaded successfully"
}
restart_backend() {
log_info "Restarting backend service on $TARGET..."
if ! ssh root@$TARGET "systemctl restart $BACKEND_SERVICE" 2>/dev/null; then
log_error "Failed to restart backend service"
exit 1
fi
log_info "Backend service restarted"
# Wait a moment for service to start
sleep 2
}
reload_nginx() {
log_info "Testing Nginx configuration on $TARGET..."
if ! ssh root@$TARGET "nginx -t" 2>/dev/null; then
log_error "Nginx configuration test failed"
exit 1
fi
log_info "Reloading Nginx..."
if ! ssh root@$TARGET "systemctl reload nginx" 2>/dev/null; then
log_error "Failed to reload Nginx"
exit 1
fi
log_info "Nginx reloaded successfully"
}
health_check() {
log_info "Running health check..."
local max_retries=5
local retry_count=0
local http_code
while [ $retry_count -lt $max_retries ]; do
http_code=$(curl -s -o /dev/null -w "%{http_code}" "http://$TARGET/api/status" || echo "000")
if [ "$http_code" = "200" ]; then
log_info "Health check passed (HTTP $http_code)"
return 0
fi
retry_count=$((retry_count + 1))
if [ $retry_count -lt $max_retries ]; then
log_warn "Health check returned HTTP $http_code, retrying... ($retry_count/$max_retries)"
sleep 2
fi
done
log_error "Health check failed after $max_retries attempts (last HTTP code: $http_code)"
exit 1
}
# Main execution
main() {
log_info "Starting deployment to $TARGET"
log_info "Frontend: $DEPLOY_FRONTEND | Backend: $DEPLOY_BACKEND"
check_prerequisites
check_ssh_connection
if [ "$DEPLOY_FRONTEND" = true ]; then
deploy_frontend
fi
if [ "$DEPLOY_BACKEND" = true ]; then
deploy_backend
restart_backend
fi
if [ "$DEPLOY_BACKEND" = true ] || [ "$DEPLOY_FRONTEND" = true ]; then
reload_nginx
fi
health_check
log_info "Deployment completed successfully!"
exit 0
}
main