#!/usr/bin/env bash # ============================================================================= # Nexus 6.0 — 全新安装脚本(1Panel + Docker Compose) # # 适用:新机已装 1Panel / Docker,空库,走 /app/install.html 安装向导 # 风格参考 1Panel quick_start.sh:分阶段检查 + 结束输出访问地址 # # 用法(公共仓库,root 下一条命令,参考 1Panel): # # curl -fsSL "http://66.154.115.8:3000/admin/Nexus/raw/branch/main/deploy/quick-install.sh" | bash # # 已 clone 到 /opt/nexus: # cd /opt/nexus && bash deploy/install-nexus-fresh.sh --skip-clone # # bash deploy/install-nexus-fresh.sh --profile 4c16g # # 公共仓库匿名 clone,无需 Gitea 令牌。NEXUS 密钥由安装脚本按机自动生成。 # ============================================================================= set -euo pipefail _install_self="$(readlink -f "${BASH_SOURCE[0]}")" if ! head -1 "$_install_self" | grep -q '^#!/'; then echo "[ERROR] 脚本文件无效。若用 curl 下载,请改用: bash deploy/download-install-fresh.sh" >&2 exit 1 fi if grep -qiE '^(Not found|404)' "$_install_self" 2>/dev/null; then echo "[ERROR] 下载到的是 Gitea 404 页面,不是安装脚本。" >&2 echo " 请: cd /opt/nexus && git pull && sudo bash deploy/install-nexus-fresh.sh --skip-clone" >&2 exit 1 fi # ── 默认配置(与 SECRETS.md / nexus-1panel 一致)── NEXUS_ROOT="${NEXUS_ROOT:-/opt/nexus}" NEXUS_GITEA_HOST="${NEXUS_GITEA_HOST:-66.154.115.8:3000}" NEXUS_GITEA_REPO="${NEXUS_GITEA_REPO:-admin/Nexus.git}" NEXUS_DOMAIN="${NEXUS_DOMAIN:-api.synaglobal.vip}" NEXUS_PROFILE="${NEXUS_PROFILE:-2c8g}" NEXUS_GIT_BRANCH="${NEXUS_GIT_BRANCH:-main}" NEXUS_RAW_BASE="${NEXUS_RAW_BASE:-http://66.154.115.8:3000/admin/Nexus/raw/branch/main}" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' BLUE='\033[0;34m' NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } step() { echo -e "${CYAN}[STEP]${NC} $*"; } usage() { cat </dev/null || true ln -sf "${NEXUS_ROOT}/deploy/nx" /usr/local/bin/nx ln -sf "${NEXUS_ROOT}/deploy/nexus-1panel.sh" /usr/local/bin/nexus-1panel ln -sf "${NEXUS_ROOT}/deploy/install-nexus-fresh.sh" /usr/local/bin/nexus-fresh ln -sf "${NEXUS_ROOT}/deploy/quick-install.sh" /usr/local/bin/nexus-install ln -sf "${NEXUS_ROOT}/deploy/install-1panel-docker.sh" /usr/local/bin/nexus-1panel-docker 2>/dev/null || true info "已注册全局命令(root 直接输入即可):" info " nexus-1panel-docker — 重装服务器(1Panel + Docker + Nexus)" info " nexus-install — 仅 Nexus Docker(curl 入口)" info " nexus-1panel — 底层 install/upgrade 脚本" info " nx — 主菜单 / nx god 上帝菜单" info " nexus-fresh — 全新安装脚本" } phase_preflight() { step "阶段 1/6 — 环境检查" if [[ "$(id -u)" -ne 0 ]]; then error "请切换到 root 再执行(不要用 sudo 包一层):" error " su -" error " bash $0 ..." exit 1 fi info "运行用户: root(无需 sudo)" if [[ ! -f /etc/os-release ]]; then error "无法识别操作系统" exit 1 fi # shellcheck disable=SC1091 source /etc/os-release info "系统: ${NAME:-Linux} ${VERSION_ID:-}" case "${ID:-}" in ubuntu|debian) info "受支持的分支: Debian/Ubuntu ✓" ;; centos|rhel|rocky|almalinux) info "受支持的分支: RHEL 系 ✓" ;; *) warn "未在官方列表中测试,可能仍可运行" ;; esac local mem_kb mem_kb="$(awk '/MemTotal/ {print $2}' /proc/meminfo 2>/dev/null || echo 0)" if [[ "$mem_kb" -lt 3500000 ]]; then warn "内存 < 4GB,建议档位 1c4g: --profile 1c4g" else info "内存: $((mem_kb / 1024 / 1024)) GiB 量级" fi } phase_1panel() { step "阶段 2/6 — 1Panel / Docker" if [[ "$SKIP_1PANEL_CHECK" != true ]]; then if command -v 1pctl >/dev/null 2>&1; then info "检测到 1Panel (1pctl)" if 1pctl version >/dev/null 2>&1; then info "1Panel: $(1pctl version 2>/dev/null | head -1 || true)" fi else warn "未检测到 1pctl — 若尚未安装 1Panel,可先执行:" warn " curl -sSL https://resource.1panel.pro/v2/quick_start.sh -o quick_start.sh" warn " bash quick_start.sh" read -r -p "继续安装 Nexus? [y/N]: " cont [[ "$cont" == "y" || "$cont" == "Y" ]] || exit 0 fi fi if ! docker compose version >/dev/null 2>&1; then error "未检测到 docker compose" error "请在 1Panel → 容器 中安装 Docker,或: apt install -y docker.io docker-compose-v2" exit 1 fi info "Docker Compose: $(docker compose version --short 2>/dev/null || docker compose version | head -1)" } phase_packages() { step "阶段 3/6 — 依赖包" if command -v apt-get >/dev/null 2>&1; then export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq git curl openssl ca-certificates iproute2 >/dev/null 2>&1 || true elif command -v dnf >/dev/null 2>&1; then dnf install -y -q git curl openssl ca-certificates iproute >/dev/null 2>&1 || true fi info "git / curl 就绪" } git_clone_url() { if [[ -z "${NEXUS_GITEA_TOKEN:-}" ]]; then echo "http://${NEXUS_GITEA_HOST}/${NEXUS_GITEA_REPO}" else echo "http://admin:${NEXUS_GITEA_TOKEN}@${NEXUS_GITEA_HOST}/${NEXUS_GITEA_REPO}" fi } phase_clone() { step "阶段 4/6 — 获取 Nexus 代码" if [[ "$SKIP_CLONE" == true ]]; then if [[ ! -d "${NEXUS_ROOT}/.git" ]]; then error "--skip-clone 但 ${NEXUS_ROOT} 不是 git 仓库" exit 1 fi load_credentials info "跳过 clone,使用现有 ${NEXUS_ROOT}" info "版本: $(git -C "$NEXUS_ROOT" log -1 --oneline 2>/dev/null || echo '?')" chmod +x "${NEXUS_ROOT}/deploy/"*.sh 2>/dev/null || true return 0 fi load_credentials local url url="$(git_clone_url)" if [[ -z "${NEXUS_GITEA_TOKEN:-}" ]]; then info "公共仓库:匿名 git clone(无需令牌)" fi mkdir -p "$(dirname "$NEXUS_ROOT")" if [[ -d "${NEXUS_ROOT}/.git" ]]; then info "仓库已存在,同步 ${NEXUS_GIT_BRANCH}..." git -C "$NEXUS_ROOT" remote set-url origin "$url" 2>/dev/null || true git -C "$NEXUS_ROOT" fetch origin "$NEXUS_GIT_BRANCH" --prune git -C "$NEXUS_ROOT" reset --hard "origin/${NEXUS_GIT_BRANCH}" else if [[ -d "$NEXUS_ROOT" ]] && [[ -n "$(ls -A "$NEXUS_ROOT" 2>/dev/null)" ]]; then error "目录非空且不是 git 仓库: $NEXUS_ROOT" exit 1 fi rm -rf "$NEXUS_ROOT" info "克隆 → $NEXUS_ROOT" git clone "$url" "$NEXUS_ROOT" git -C "$NEXUS_ROOT" checkout "$NEXUS_GIT_BRANCH" 2>/dev/null || true fi load_credentials info "版本: $(git -C "$NEXUS_ROOT" log -1 --oneline)" chmod +x "${NEXUS_ROOT}/deploy/"*.sh 2>/dev/null || true } phase_install_stack() { step "阶段 5/6 — Docker 构建与启动(全新库,约 10~20 分钟)" export NEXUS_ROOT NEXUS_DOMAIN NEXUS_PROFILE bash "${NEXUS_ROOT}/deploy/nexus-1panel.sh" install \ --fresh \ --skip-clone \ --profile "$NEXUS_PROFILE" \ --domain "$NEXUS_DOMAIN" } phase_post() { step "阶段 6/6 — 收尾" install_root_commands local port health port="8600" health="$(curl -sf "http://127.0.0.1:${port}/health" 2>/dev/null || echo "pending")" echo "" echo -e "${GREEN}╔══════════════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}║${NC} ${GREEN}Nexus 全新安装完成${NC} ${GREEN}║${NC}" echo -e "${GREEN}╠══════════════════════════════════════════════════════════════╣${NC}" echo -e "${GREEN}║${NC} 本地健康: http://127.0.0.1:${port}/health → ${health} ${GREEN}║${NC}" echo -e "${GREEN}║${NC} ${GREEN}║${NC}" echo -e "${GREEN}║${NC} ${YELLOW}① 浏览器完成安装向导(必做)${NC} ${GREEN}║${NC}" echo -e "${GREEN}║${NC} https://${NEXUS_DOMAIN}/app/install.html ${GREEN}║${NC}" echo -e "${GREEN}║${NC} ${GREEN}║${NC}" echo -e "${GREEN}║${NC} ${YELLOW}② 1Panel 创建网站并反代${NC} ${GREEN}║${NC}" echo -e "${GREEN}║${NC} 目标: http://127.0.0.1:${port} ${GREEN}║${NC}" echo -e "${GREEN}║${NC} 示例: ${NEXUS_ROOT}/deploy/1panel/openresty-nexus.conf.example ${GREEN}║${NC}" echo -e "${GREEN}║${NC} ${GREEN}║${NC}" echo -e "${GREEN}║${NC} ${YELLOW}③ 日常运维(上帝菜单)${NC} ${GREEN}║${NC}" echo -e "${GREEN}║${NC} nx god # 重启 Python / 升级 / 日志 / 备份 ${GREEN}║${NC}" echo -e "${GREEN}║${NC} nx # 主菜单 ${GREEN}║${NC}" echo -e "${GREEN}╚══════════════════════════════════════════════════════════════╝${NC}" echo "" } main() { banner if [[ "$SKIP_CLONE" == true && -d "${NEXUS_ROOT}/deploy" ]]; then install_root_commands fi phase_preflight phase_1panel phase_packages phase_clone phase_install_stack phase_post } main "$@"