527 lines
16 KiB
Bash
527 lines
16 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
# ================================================================
|
||
|
|
# Nexus 6.0 — One-Click Install Script
|
||
|
|
#
|
||
|
|
# Usage:
|
||
|
|
# curl -fsSL https://YOUR_DOMAIN/deploy/install.sh | sudo bash -s -- --domain nexus.example.com
|
||
|
|
# sudo bash install.sh --domain nexus.example.com
|
||
|
|
#
|
||
|
|
# Supports: Ubuntu 20.04+, Debian 11+, CentOS 7/8, Rocky 8/9, AlmaLinux 8/9
|
||
|
|
# Auto-detects BT Panel (宝塔面板) and adapts paths accordingly.
|
||
|
|
# ================================================================
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
# ── Colors ──
|
||
|
|
RED='\033[0;31m'
|
||
|
|
GREEN='\033[0;32m'
|
||
|
|
YELLOW='\033[1;33m'
|
||
|
|
NC='\033[0m'
|
||
|
|
|
||
|
|
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
||
|
|
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||
|
|
error() { echo -e "${RED}[ERROR]${NC} $*"; }
|
||
|
|
|
||
|
|
# ── Helper: Idempotent config write ──
|
||
|
|
write_config() {
|
||
|
|
local target="$1" content="$2"
|
||
|
|
if [ -f "$target" ]; then
|
||
|
|
local existing
|
||
|
|
existing=$(cat "$target" 2>/dev/null || true)
|
||
|
|
if [ "$existing" = "$content" ]; then
|
||
|
|
info " [skip] $target (unchanged)"
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
info " [update] $target (content changed)"
|
||
|
|
else
|
||
|
|
info " [create] $target"
|
||
|
|
fi
|
||
|
|
echo "$content" > "$target"
|
||
|
|
}
|
||
|
|
|
||
|
|
# ── Defaults ──
|
||
|
|
DOMAIN=""
|
||
|
|
DEPLOY_DIR=""
|
||
|
|
PORT=8600
|
||
|
|
SKIP_NGINX=false
|
||
|
|
SKIP_SUPERVISOR=false
|
||
|
|
BT_MODE=false
|
||
|
|
NEXUS_REPO=""
|
||
|
|
|
||
|
|
# ── Parse Arguments ──
|
||
|
|
while [[ $# -gt 0 ]]; do
|
||
|
|
case $1 in
|
||
|
|
--domain) DOMAIN="$2"; shift 2 ;;
|
||
|
|
--deploy-dir) DEPLOY_DIR="$2"; shift 2 ;;
|
||
|
|
--port) PORT="$2"; shift 2 ;;
|
||
|
|
--skip-nginx) SKIP_NGINX=true; shift ;;
|
||
|
|
--skip-supervisor) SKIP_SUPERVISOR=true; shift ;;
|
||
|
|
--repo) NEXUS_REPO="$2"; shift 2 ;;
|
||
|
|
-h|--help)
|
||
|
|
echo "Usage: sudo bash install.sh --domain DOMAIN [options]"
|
||
|
|
echo ""
|
||
|
|
echo "Options:"
|
||
|
|
echo " --domain DOMAIN Required. Domain or IP for Nginx server_name"
|
||
|
|
echo " --deploy-dir PATH Installation directory (auto-detected)"
|
||
|
|
echo " --port PORT uvicorn port (default: 8600)"
|
||
|
|
echo " --skip-nginx Skip Nginx configuration"
|
||
|
|
echo " --skip-supervisor Skip Supervisor configuration"
|
||
|
|
echo " --repo URL Git repository URL (optional, for cloning)"
|
||
|
|
exit 0 ;;
|
||
|
|
*) shift ;;
|
||
|
|
esac
|
||
|
|
done
|
||
|
|
|
||
|
|
# ── Banner ──
|
||
|
|
echo ""
|
||
|
|
echo "=========================================="
|
||
|
|
echo " Nexus 6.0 Install Script"
|
||
|
|
echo "=========================================="
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# ================================================================
|
||
|
|
# Phase 1: Pre-flight Checks
|
||
|
|
# ================================================================
|
||
|
|
|
||
|
|
info "Phase 1/7: Pre-flight checks..."
|
||
|
|
|
||
|
|
# 1.1 Must run as root
|
||
|
|
if [ "$(id -u)" -ne 0 ]; then
|
||
|
|
error "This script must be run as root. Use: sudo bash install.sh"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
# 1.2 Domain is required
|
||
|
|
if [ -z "$DOMAIN" ]; then
|
||
|
|
error "--domain is required. Usage: sudo bash install.sh --domain nexus.example.com"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
# 1.3 OS detection
|
||
|
|
if [ ! -f /etc/os-release ]; then
|
||
|
|
error "Cannot detect OS. /etc/os-release not found."
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
OS_ID=$(grep '^ID=' /etc/os-release | head -1 | cut -d'=' -f2 | tr -d '"' | cut -d'-' -f1)
|
||
|
|
OS_VERSION=$(grep '^VERSION_ID=' /etc/os-release | head -1 | cut -d'=' -f2 | tr -d '"')
|
||
|
|
|
||
|
|
case "$OS_ID" in
|
||
|
|
ubuntu|debian) PKG_MANAGER="apt" ;;
|
||
|
|
centos|rocky|almalinux|rhel) PKG_MANAGER="yum" ;;
|
||
|
|
*)
|
||
|
|
warn "Unsupported OS: $OS_ID. Script may still work but is untested."
|
||
|
|
PKG_MANAGER="apt"
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
info " OS: $OS_ID $OS_VERSION (pkg: $PKG_MANAGER)"
|
||
|
|
|
||
|
|
# 1.4 BT Panel detection
|
||
|
|
if [ -d "/www/server/panel" ] && [ -f "/www/server/panel/class/common.py" ]; then
|
||
|
|
BT_MODE=true
|
||
|
|
info " BT Panel: detected"
|
||
|
|
else
|
||
|
|
info " BT Panel: not detected (standard mode)"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# 1.5 Set deploy directory
|
||
|
|
if [ -z "$DEPLOY_DIR" ]; then
|
||
|
|
if [ "$BT_MODE" = true ]; then
|
||
|
|
DEPLOY_DIR="/www/wwwroot/$DOMAIN"
|
||
|
|
else
|
||
|
|
DEPLOY_DIR="/opt/nexus"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
VENV_DIR="$DEPLOY_DIR/venv"
|
||
|
|
|
||
|
|
# Set log paths early (used in multiple phases)
|
||
|
|
if [ "$BT_MODE" = true ]; then
|
||
|
|
LOG_DIR="/www/wwwlogs"
|
||
|
|
else
|
||
|
|
LOG_DIR="/var/log/nexus"
|
||
|
|
fi
|
||
|
|
|
||
|
|
info " Deploy dir: $DEPLOY_DIR"
|
||
|
|
info " Domain: $DOMAIN"
|
||
|
|
info " Port: $PORT"
|
||
|
|
|
||
|
|
# ================================================================
|
||
|
|
# Phase 2: System Dependencies
|
||
|
|
# ================================================================
|
||
|
|
|
||
|
|
info "Phase 2/7: Installing system dependencies..."
|
||
|
|
|
||
|
|
if [ "$PKG_MANAGER" = "apt" ]; then
|
||
|
|
export DEBIAN_FRONTEND=noninteractive
|
||
|
|
apt-get update -qq
|
||
|
|
apt-get install -y -qq \
|
||
|
|
python3 python3-venv python3-pip python3-dev \
|
||
|
|
build-essential libssl-dev libffi-dev default-libmysqlclient-dev \
|
||
|
|
git curl >/dev/null 2>&1 || warn "Some apt packages failed to install (may already exist)"
|
||
|
|
elif [ "$PKG_MANAGER" = "yum" ]; then
|
||
|
|
if command -v dnf >/dev/null 2>&1; then
|
||
|
|
dnf install -y -q \
|
||
|
|
python3 python3-devel python3-pip \
|
||
|
|
gcc openssl-devel libffi-devel mysql-devel \
|
||
|
|
git curl >/dev/null 2>&1 || warn "Some dnf packages failed to install"
|
||
|
|
else
|
||
|
|
yum install -y -q \
|
||
|
|
python3 python3-devel python3-pip \
|
||
|
|
gcc openssl-devel libffi-devel mysql-devel \
|
||
|
|
git curl >/dev/null 2>&1 || warn "Some yum packages failed to install"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
# ================================================================
|
||
|
|
# Phase 3: Python 3.10+ Resolution
|
||
|
|
# ================================================================
|
||
|
|
|
||
|
|
info "Phase 3/7: Resolving Python 3.10+..."
|
||
|
|
|
||
|
|
PYTHON=""
|
||
|
|
CANDIDATES="python3.12 python3.11 python3.10 /usr/bin/python3.12 /usr/bin/python3.11 /usr/bin/python3.10 python3"
|
||
|
|
|
||
|
|
# Add BT Panel Python paths
|
||
|
|
if [ "$BT_MODE" = true ]; then
|
||
|
|
for p in /www/server/python-manager/versions/*/bin/python3.*; do
|
||
|
|
[ -x "$p" ] && CANDIDATES="$CANDIDATES $p"
|
||
|
|
done
|
||
|
|
fi
|
||
|
|
|
||
|
|
for candidate in $CANDIDATES; do
|
||
|
|
if command -v "$candidate" >/dev/null 2>&1 || [ -x "$candidate" ]; then
|
||
|
|
ver=$("$candidate" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null || true)
|
||
|
|
if [ -n "$ver" ]; then
|
||
|
|
major=$(echo "$ver" | cut -d'.' -f1)
|
||
|
|
minor=$(echo "$ver" | cut -d'.' -f2)
|
||
|
|
if [ "$major" -eq 3 ] && [ "${minor:-0}" -ge 10 ] 2>/dev/null; then
|
||
|
|
PYTHON="$candidate"
|
||
|
|
break
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
|
||
|
|
# Fallback: install Python 3.12 on Ubuntu via deadsnakes PPA
|
||
|
|
if [ -z "$PYTHON" ] && [ "$OS_ID" = "ubuntu" ]; then
|
||
|
|
warn " Python 3.10+ not found. Adding deadsnakes PPA..."
|
||
|
|
export DEBIAN_FRONTEND=noninteractive
|
||
|
|
apt-get install -y -qq software-properties-common >/dev/null 2>&1
|
||
|
|
add-apt-repository -y ppa:deadsnakes/ppa >/dev/null 2>&1
|
||
|
|
apt-get update -qq
|
||
|
|
apt-get install -y -qq python3.12 python3.12-venv python3.12-dev >/dev/null 2>&1
|
||
|
|
if command -v python3.12 >/dev/null 2>&1; then
|
||
|
|
PYTHON="python3.12"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [ -z "$PYTHON" ]; then
|
||
|
|
error "Python 3.10+ is required but not found."
|
||
|
|
error "Install Python 3.10+ manually and re-run."
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
PYTHON_VERSION=$("$PYTHON" --version 2>&1)
|
||
|
|
info " Using: $PYTHON ($PYTHON_VERSION)"
|
||
|
|
|
||
|
|
# ================================================================
|
||
|
|
# Phase 4: Application Deployment
|
||
|
|
# ================================================================
|
||
|
|
|
||
|
|
info "Phase 4/7: Deploying application..."
|
||
|
|
|
||
|
|
# 4.1 Create deploy directory
|
||
|
|
mkdir -p "$DEPLOY_DIR"
|
||
|
|
|
||
|
|
# 4.2 Download / Clone Nexus
|
||
|
|
if [ -d "$DEPLOY_DIR/server" ] && [ -d "$DEPLOY_DIR/web" ]; then
|
||
|
|
info " Application files already exist in $DEPLOY_DIR (skipping download)"
|
||
|
|
if [ -d "$DEPLOY_DIR/.git" ]; then
|
||
|
|
info " Git repo detected, pulling latest..."
|
||
|
|
(cd "$DEPLOY_DIR" && git pull --ff-only 2>/dev/null || warn " git pull failed (may have local changes)")
|
||
|
|
fi
|
||
|
|
elif [ -n "$NEXUS_REPO" ]; then
|
||
|
|
info " Cloning from $NEXUS_REPO..."
|
||
|
|
git clone "$NEXUS_REPO" "$DEPLOY_DIR" 2>/dev/null || {
|
||
|
|
error "git clone failed. Check the repository URL."
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
else
|
||
|
|
error "No application files found in $DEPLOY_DIR and no --repo URL provided."
|
||
|
|
error "Either:"
|
||
|
|
error " 1. Copy Nexus files to $DEPLOY_DIR manually and re-run"
|
||
|
|
error " 2. Use --repo https://your-gitea-url/Nexus.git"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
# 4.3 Create Python venv
|
||
|
|
if [ -d "$VENV_DIR/bin" ] && "$VENV_DIR/bin/python" -c 'import sys; v=sys.version_info; assert v.major==3 and v.minor>=10' 2>/dev/null; then
|
||
|
|
info " venv already exists with Python 3.10+ (skipping)"
|
||
|
|
else
|
||
|
|
info " Creating Python venv..."
|
||
|
|
rm -rf "$VENV_DIR"
|
||
|
|
"$PYTHON" -m venv "$VENV_DIR"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# 4.4 Install pip dependencies
|
||
|
|
info " Installing Python dependencies (this may take a few minutes)..."
|
||
|
|
"$VENV_DIR/bin/pip" install -q --upgrade pip
|
||
|
|
"$VENV_DIR/bin/pip" install -q -r "$DEPLOY_DIR/requirements.txt" 2>/dev/null || {
|
||
|
|
warn " pip install had some warnings, but continuing..."
|
||
|
|
}
|
||
|
|
|
||
|
|
# 4.5 Create log directory
|
||
|
|
mkdir -p "$LOG_DIR"
|
||
|
|
|
||
|
|
# 4.6 Create backup directory
|
||
|
|
mkdir -p "$DEPLOY_DIR/backups"
|
||
|
|
|
||
|
|
# ================================================================
|
||
|
|
# Phase 5: Supervisor Configuration
|
||
|
|
# ================================================================
|
||
|
|
|
||
|
|
if [ "$SKIP_SUPERVISOR" = true ]; then
|
||
|
|
warn "Phase 5/7: Skipping Supervisor (per --skip-supervisor)"
|
||
|
|
else
|
||
|
|
info "Phase 5/7: Configuring Supervisor..."
|
||
|
|
|
||
|
|
# Calculate worker count
|
||
|
|
WORKERS=$(nproc 2>/dev/null || echo 2)
|
||
|
|
[ "$WORKERS" -gt 4 ] && WORKERS=4
|
||
|
|
[ "$WORKERS" -lt 1 ] && WORKERS=1
|
||
|
|
|
||
|
|
# Set Supervisor config path
|
||
|
|
if [ "$BT_MODE" = true ]; then
|
||
|
|
SUPERVISOR_CONF_DIR="/www/server/panel/plugin/supervisor/profile"
|
||
|
|
CONF_FILE="$SUPERVISOR_CONF_DIR/nexus.ini"
|
||
|
|
else
|
||
|
|
SUPERVISOR_CONF_DIR="/etc/supervisor/conf.d"
|
||
|
|
CONF_FILE="$SUPERVISOR_CONF_DIR/nexus.conf"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Generate Supervisor config
|
||
|
|
SUPERVISOR_CONF="[program:nexus]
|
||
|
|
command=$VENV_DIR/bin/uvicorn server.main:app --host 0.0.0.0 --port $PORT --workers $WORKERS --loop uvloop --http httptools --log-level info
|
||
|
|
directory=$DEPLOY_DIR
|
||
|
|
user=root
|
||
|
|
autostart=true
|
||
|
|
autorestart=true
|
||
|
|
startretries=10
|
||
|
|
startsecs=3
|
||
|
|
stopwaitsecs=10
|
||
|
|
stopsignal=INT
|
||
|
|
environment=PATH=\"$VENV_DIR/bin:%(ENV_PATH)s\",HOME=\"/root\",NEXUS_WORKERS=\"$WORKERS\"
|
||
|
|
stderr_logfile=$LOG_DIR/nexus_error.log
|
||
|
|
stdout_logfile=$LOG_DIR/nexus_access.log
|
||
|
|
stderr_logfile_maxbytes=50MB
|
||
|
|
stdout_logfile_maxbytes=50MB
|
||
|
|
stderr_logfile_backups=5
|
||
|
|
stdout_logfile_backups=5"
|
||
|
|
|
||
|
|
# Write config (idempotent)
|
||
|
|
mkdir -p "$SUPERVISOR_CONF_DIR"
|
||
|
|
write_config "$CONF_FILE" "$SUPERVISOR_CONF"
|
||
|
|
|
||
|
|
# Ensure Supervisor is running
|
||
|
|
if ! supervisorctl status >/dev/null 2>&1; then
|
||
|
|
if [ "$BT_MODE" = true ]; then
|
||
|
|
if [ -f /etc/init.d/supervisor ]; then
|
||
|
|
/etc/init.d/supervisor start >/dev/null 2>&1 || true
|
||
|
|
fi
|
||
|
|
else
|
||
|
|
systemctl start supervisor >/dev/null 2>&1 || true
|
||
|
|
fi
|
||
|
|
sleep 2
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Reload Supervisor config
|
||
|
|
supervisorctl reread >/dev/null 2>&1 || true
|
||
|
|
supervisorctl update >/dev/null 2>&1 || true
|
||
|
|
info " Supervisor config written to $CONF_FILE (workers=$WORKERS)"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# ================================================================
|
||
|
|
# Phase 6: Nginx Configuration
|
||
|
|
# ================================================================
|
||
|
|
|
||
|
|
if [ "$SKIP_NGINX" = true ]; then
|
||
|
|
warn "Phase 6/7: Skipping Nginx (per --skip-nginx)"
|
||
|
|
else
|
||
|
|
info "Phase 6/7: Configuring Nginx..."
|
||
|
|
|
||
|
|
if [ "$BT_MODE" = true ]; then
|
||
|
|
NGINX_CONF_FILE="/www/server/panel/vhost/nginx/$DOMAIN.conf"
|
||
|
|
NGINX_RELOAD_CMD="/www/server/nginx/sbin/nginx -s reload"
|
||
|
|
NGINX_TEST_CMD="/www/server/nginx/sbin/nginx -t"
|
||
|
|
NGINX_ACCESS_LOG="/www/wwwlogs/$DOMAIN.log"
|
||
|
|
NGINX_ERROR_LOG="/www/wwwlogs/$DOMAIN.error.log"
|
||
|
|
else
|
||
|
|
NGINX_CONF_FILE="/etc/nginx/sites-available/nexus"
|
||
|
|
NGINX_RELOAD_CMD="systemctl reload nginx"
|
||
|
|
NGINX_TEST_CMD="nginx -t"
|
||
|
|
NGINX_ACCESS_LOG="/var/log/nginx/nexus_access.log"
|
||
|
|
NGINX_ERROR_LOG="/var/log/nginx/nexus_error.log"
|
||
|
|
fi
|
||
|
|
|
||
|
|
NGINX_CONF="# Nexus 6.0 — Nginx Reverse Proxy
|
||
|
|
# Auto-generated by install.sh
|
||
|
|
upstream nexus_api {
|
||
|
|
server 127.0.0.1:$PORT;
|
||
|
|
keepalive 32;
|
||
|
|
}
|
||
|
|
|
||
|
|
server {
|
||
|
|
listen 80;
|
||
|
|
server_name $DOMAIN;
|
||
|
|
|
||
|
|
# Reverse proxy to Nexus (uvicorn)
|
||
|
|
location / {
|
||
|
|
proxy_pass http://nexus_api;
|
||
|
|
proxy_set_header Host \$host;
|
||
|
|
proxy_set_header X-Real-IP \$remote_addr;
|
||
|
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||
|
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
||
|
|
proxy_read_timeout 300s;
|
||
|
|
proxy_send_timeout 300s;
|
||
|
|
}
|
||
|
|
|
||
|
|
# WebSocket support (terminal, alerts)
|
||
|
|
location /ws/ {
|
||
|
|
proxy_pass http://nexus_api;
|
||
|
|
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;
|
||
|
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
||
|
|
proxy_read_timeout 3600s;
|
||
|
|
}
|
||
|
|
|
||
|
|
# Static assets caching
|
||
|
|
location /app/vendor/ {
|
||
|
|
proxy_pass http://nexus_api;
|
||
|
|
expires 7d;
|
||
|
|
add_header Cache-Control \"public, immutable\";
|
||
|
|
}
|
||
|
|
|
||
|
|
# Block sensitive files
|
||
|
|
location ~ ^/(\\.env|\\.git|\\.svn) {
|
||
|
|
return 404;
|
||
|
|
}
|
||
|
|
|
||
|
|
# Block config.json access
|
||
|
|
location ~ /data/config\\.json$ {
|
||
|
|
return 404;
|
||
|
|
}
|
||
|
|
|
||
|
|
# Upload limit
|
||
|
|
client_max_body_size 500m;
|
||
|
|
|
||
|
|
# Well-known for SSL cert validation
|
||
|
|
location ~ \\.well-known {
|
||
|
|
allow all;
|
||
|
|
}
|
||
|
|
|
||
|
|
access_log $NGINX_ACCESS_LOG;
|
||
|
|
error_log $NGINX_ERROR_LOG;
|
||
|
|
}"
|
||
|
|
|
||
|
|
# Write Nginx config
|
||
|
|
if [ "$BT_MODE" = true ]; then
|
||
|
|
write_config "$NGINX_CONF_FILE" "$NGINX_CONF"
|
||
|
|
else
|
||
|
|
mkdir -p /etc/nginx/sites-available
|
||
|
|
write_config "$NGINX_CONF_FILE" "$NGINX_CONF"
|
||
|
|
if [ ! -L /etc/nginx/sites-enabled/nexus ]; then
|
||
|
|
ln -sf "$NGINX_CONF_FILE" /etc/nginx/sites-enabled/nexus
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Test and reload Nginx
|
||
|
|
if $NGINX_TEST_CMD >/dev/null 2>&1; then
|
||
|
|
$NGINX_RELOAD_CMD >/dev/null 2>&1 || warn " Nginx reload failed"
|
||
|
|
info " Nginx config written to $NGINX_CONF_FILE"
|
||
|
|
else
|
||
|
|
warn " Nginx config test failed. Please check $NGINX_CONF_FILE manually"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
# ================================================================
|
||
|
|
# Phase 7: Start Application + Verify
|
||
|
|
# ================================================================
|
||
|
|
|
||
|
|
info "Phase 7/7: Starting application..."
|
||
|
|
|
||
|
|
# Start via Supervisor
|
||
|
|
if [ "$SKIP_SUPERVISOR" = false ]; then
|
||
|
|
supervisorctl start nexus >/dev/null 2>&1 || supervisorctl restart nexus >/dev/null 2>&1 || true
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Wait for health check
|
||
|
|
HEALTH_OK=false
|
||
|
|
for i in $(seq 1 15); do
|
||
|
|
if curl -sf "http://127.0.0.1:$PORT/health" >/dev/null 2>&1; then
|
||
|
|
HEALTH_OK=true
|
||
|
|
break
|
||
|
|
fi
|
||
|
|
sleep 2
|
||
|
|
done
|
||
|
|
|
||
|
|
# ── Print Results ──
|
||
|
|
echo ""
|
||
|
|
echo "=========================================="
|
||
|
|
|
||
|
|
if [ "$HEALTH_OK" = true ]; then
|
||
|
|
echo -e " ${GREEN}Nexus installed successfully!${NC}"
|
||
|
|
else
|
||
|
|
echo -e " ${YELLOW}Nexus process started but health check pending.${NC}"
|
||
|
|
echo -e " ${YELLOW}It may need a few more seconds to start up.${NC}"
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "=========================================="
|
||
|
|
echo ""
|
||
|
|
echo " Deploy: $DEPLOY_DIR"
|
||
|
|
echo " Domain: $DOMAIN"
|
||
|
|
echo " Port: $PORT"
|
||
|
|
echo " Workers: ${WORKERS:-N/A}"
|
||
|
|
echo " BT Panel: $BT_MODE"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
if [ "$HEALTH_OK" = true ]; then
|
||
|
|
echo -e " ${GREEN}Next step:${NC} Open your browser and complete the web install wizard:"
|
||
|
|
echo ""
|
||
|
|
echo " http://$DOMAIN/app/install.html"
|
||
|
|
echo ""
|
||
|
|
echo " The wizard will guide you through:"
|
||
|
|
echo " Step 1: Welcome & prerequisites"
|
||
|
|
echo " Step 2: Environment check"
|
||
|
|
echo " Step 3: MySQL + Redis configuration"
|
||
|
|
echo " Step 4: Admin account + brand"
|
||
|
|
echo " Step 5: Complete"
|
||
|
|
else
|
||
|
|
echo " Troubleshooting:"
|
||
|
|
echo " supervisorctl status nexus"
|
||
|
|
echo " tail -f $LOG_DIR/nexus_error.log"
|
||
|
|
echo " curl http://127.0.0.1:$PORT/health"
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
echo " Post-install:"
|
||
|
|
echo " 1. Configure SSL (HTTPS)"
|
||
|
|
if [ "$BT_MODE" = true ]; then
|
||
|
|
echo " BT Panel -> Website -> $DOMAIN -> SSL"
|
||
|
|
else
|
||
|
|
echo " certbot --nginx -d $DOMAIN"
|
||
|
|
fi
|
||
|
|
echo " 2. Set up health monitor crontab:"
|
||
|
|
echo " * * * * * $DEPLOY_DIR/deploy/health_monitor.sh"
|
||
|
|
echo " 3. Set up database backup crontab:"
|
||
|
|
echo " 0 3 * * * $DEPLOY_DIR/deploy/db_backup.sh"
|
||
|
|
echo ""
|
||
|
|
echo " Management:"
|
||
|
|
echo " supervisorctl status nexus"
|
||
|
|
echo " supervisorctl restart nexus"
|
||
|
|
echo " supervisorctl stop nexus"
|
||
|
|
echo ""
|