feat: initial project scaffold for lxs multi-tool
- add main entrypoint with interactive menu and CLI dispatcher (lxs.sh) - add shared helpers library with colors, loggers, and spinner (lib/common.sh) - add app installers for coolify, pterodactyl, uptime-kuma, cloudpanel, and proxmox (apps/) - add system tools for monitoring, benchmarking, and hardening (tools/) - add VERSION file (0.1.0) as single source of truth for releases - add MIT LICENSE - expand README with usage, project structure, and release workflow
This commit is contained in:
Executable
+248
@@ -0,0 +1,248 @@
|
||||
#!/bin/bash
|
||||
|
||||
# LXS - Uptime Kuma Installation Script
|
||||
# Description: Install and manage Uptime Kuma monitoring tool
|
||||
# Author: LXS
|
||||
# Date: 2025
|
||||
|
||||
# Load LXS common library (colors, separator, run_spinner, loggers, helpers)
|
||||
LXS_RAW_BASE="${LXS_RAW_BASE:-https://git.hyko.cx/hykocx/lxs/raw/branch/main}"
|
||||
_lib=$(curl -fsSL "${LXS_RAW_BASE}/lib/common.sh") || { echo "Failed to fetch lib/common.sh" >&2; exit 1; }
|
||||
eval "$_lib"
|
||||
unset _lib
|
||||
export LXS_LOG_FILE="/tmp/lxs_uptime_kuma.log"
|
||||
|
||||
require_root "$0" "$@"
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Configuration
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
INSTALL_DIR="/opt/uptime-kuma"
|
||||
SERVICE_NAME="uptime-kuma"
|
||||
PORT=3001
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Helper Functions
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
is_installed() {
|
||||
[ -d "$INSTALL_DIR" ] && systemctl list-unit-files | grep -q "$SERVICE_NAME.service"
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Installation Functions
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
install_dependencies() {
|
||||
apt_noninteractive
|
||||
|
||||
run_spinner "Updating system..." "apt update -qq && apt upgrade -y -qq -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold'"
|
||||
run_spinner "Installing dependencies..." "apt install -y -qq curl git wget -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold'"
|
||||
run_spinner "Adding Node.js repository..." "curl -fsSL https://deb.nodesource.com/setup_20.x | bash -"
|
||||
run_spinner "Installing Node.js..." "apt install -y -qq nodejs -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold'"
|
||||
}
|
||||
|
||||
configure_domain_ssl() {
|
||||
local domain=$1
|
||||
local email=$2
|
||||
|
||||
run_spinner "Installing Nginx..." "apt install -y -qq nginx -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold'"
|
||||
run_spinner "Installing Certbot..." "apt install -y -qq certbot python3-certbot-nginx -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold'"
|
||||
|
||||
cat > /etc/nginx/sites-available/$domain <<EOF
|
||||
server {
|
||||
listen 80;
|
||||
server_name $domain;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:$PORT;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
ln -sf /etc/nginx/sites-available/$domain /etc/nginx/sites-enabled/
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
nginx -t && systemctl restart nginx
|
||||
certbot --nginx -d $domain --non-interactive --agree-tos --email $email --redirect 2>/dev/null
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Main Installation
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
install_uptime_kuma() {
|
||||
local start_time=$(date +%s)
|
||||
|
||||
# Configure non-interactive mode globally
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export NEEDRESTART_MODE=a
|
||||
export NEEDRESTART_SUSPEND=1
|
||||
|
||||
echo -e "${WHITE}${BOLD}UPTIME KUMA INSTALLATION${NC}\n"
|
||||
|
||||
if is_installed; then
|
||||
echo -e "${YELLOW}Uptime Kuma is already installed!${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "[1/4] Installing dependencies..."
|
||||
install_dependencies
|
||||
echo ""
|
||||
|
||||
echo "[2/4] Cloning repository..."
|
||||
run_spinner "Downloading from GitHub..." "git clone https://github.com/louislam/uptime-kuma.git '$INSTALL_DIR'"
|
||||
echo ""
|
||||
|
||||
echo "[3/4] Installing Uptime Kuma..."
|
||||
cd "$INSTALL_DIR"
|
||||
run_spinner "Running npm setup..." "npm run setup"
|
||||
echo ""
|
||||
|
||||
echo "[4/4] Creating service..."
|
||||
cat > /etc/systemd/system/$SERVICE_NAME.service <<EOF
|
||||
[Unit]
|
||||
Description=Uptime Kuma
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=$INSTALL_DIR
|
||||
ExecStart=/usr/bin/npm run start-server
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
run_spinner "Starting service..." "systemctl daemon-reload && systemctl enable $SERVICE_NAME && systemctl start $SERVICE_NAME"
|
||||
sleep 5
|
||||
|
||||
local duration=$(( $(date +%s) - start_time ))
|
||||
local server_ip=$(get_public_ip)
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}${BOLD}Installation Completed!${NC}"
|
||||
echo -e "${GRAY}Time: $((duration / 60))m $((duration % 60))s${NC}"
|
||||
echo ""
|
||||
echo -e "${CYAN}Access URL: ${BOLD}http://$server_ip:$PORT${NC}"
|
||||
echo ""
|
||||
|
||||
# Optional domain configuration
|
||||
echo -e "${WHITE}Configure domain with SSL? (y/n)${NC}"
|
||||
read -n 1 -r
|
||||
echo ""
|
||||
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
read -p "Domain name: " DOMAIN_NAME
|
||||
read -p "Email for SSL: " EMAIL
|
||||
echo ""
|
||||
configure_domain_ssl "$DOMAIN_NAME" "$EMAIL"
|
||||
[ $? -eq 0 ] && echo -e "${GREEN}[✓] Domain configured: ${BOLD}https://$DOMAIN_NAME${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${WHITE}Next steps:${NC}"
|
||||
echo -e "1. Visit the URL above"
|
||||
echo -e "2. Choose SQLite database"
|
||||
echo -e "3. Create admin account"
|
||||
}
|
||||
|
||||
update_uptime_kuma() {
|
||||
echo -e "${WHITE}${BOLD}UPTIME KUMA UPDATE${NC}\n"
|
||||
|
||||
# Configure non-interactive mode
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export NEEDRESTART_MODE=a
|
||||
export NEEDRESTART_SUSPEND=1
|
||||
|
||||
if ! is_installed; then
|
||||
echo -e "${RED}Uptime Kuma is not installed!${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local start_time=$(date +%s)
|
||||
|
||||
run_spinner "Stopping service..." "systemctl stop $SERVICE_NAME"
|
||||
|
||||
BACKUP_DIR="${INSTALL_DIR}_backup_$(date +%Y%m%d_%H%M%S)"
|
||||
[ -d "$INSTALL_DIR/data" ] && run_spinner "Backing up..." "cp -r '$INSTALL_DIR/data' '$BACKUP_DIR'"
|
||||
|
||||
cd "$INSTALL_DIR"
|
||||
run_spinner "Pulling updates..." "git fetch --all && git checkout master && git pull"
|
||||
run_spinner "Updating dependencies..." "npm run setup"
|
||||
run_spinner "Starting service..." "systemctl start $SERVICE_NAME"
|
||||
|
||||
local duration=$(( $(date +%s) - start_time ))
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}${BOLD}Update Completed!${NC}"
|
||||
echo -e "${GRAY}Time: $((duration / 60))m $((duration % 60))s${NC}"
|
||||
echo -e "${CYAN}Access: ${BOLD}http://$(get_public_ip):$PORT${NC}"
|
||||
}
|
||||
|
||||
show_status() {
|
||||
echo -e "${WHITE}${BOLD}UPTIME KUMA STATUS${NC}\n"
|
||||
|
||||
if ! is_installed; then
|
||||
echo -e "${RED}Uptime Kuma is not installed!${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if systemctl is-active --quiet $SERVICE_NAME; then
|
||||
echo -e "${GREEN}Service is running${NC}\n"
|
||||
systemctl status $SERVICE_NAME --no-pager | head -10
|
||||
echo ""
|
||||
echo -e "${CYAN}Access: ${BOLD}http://$(get_public_ip):$PORT${NC}"
|
||||
else
|
||||
echo -e "${RED}Service is not running${NC}"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Main Menu
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
show_menu() {
|
||||
clear
|
||||
echo -e "${WHITE}${BOLD}UPTIME KUMA MANAGEMENT${NC}\n"
|
||||
echo -e " ${GREEN}[1]${NC} Install Uptime Kuma"
|
||||
echo -e " ${YELLOW}[2]${NC} Update Uptime Kuma"
|
||||
echo -e " ${CYAN}[3]${NC} View Status"
|
||||
echo -e " ${RED}[0]${NC} Back to main menu"
|
||||
echo ""
|
||||
echo -n "Choice [0-3]: "
|
||||
}
|
||||
|
||||
main() {
|
||||
while true; do
|
||||
show_menu
|
||||
read -r choice
|
||||
echo ""
|
||||
|
||||
case $choice in
|
||||
1) install_uptime_kuma ;;
|
||||
2) update_uptime_kuma ;;
|
||||
3) show_status ;;
|
||||
0) return 0 ;;
|
||||
*) echo -e "${RED}Invalid option${NC}" ;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
read -p "Press Enter to continue..."
|
||||
done
|
||||
}
|
||||
|
||||
main
|
||||
Reference in New Issue
Block a user