Files
Nexus/deploy/install-nexus-fresh.sh
T
Nexus Deploy 61b8d7d419 fix(deploy): health_monitor Docker 适配与巡检第三轮修补
Docker 生产用 docker restart;读 .env.prod 端口与容器 Telegram;已归档跳过全量热同步。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 22:25:27 +08:00

310 lines
13 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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 <<EOF
Nexus 6.0 全新安装(1Panel + Docker
sudo bash install-nexus-fresh.sh [选项]
选项:
--domain NAME 公网域名(默认: ${NEXUS_DOMAIN}
--profile NAME 资源档位 1c4g|2c8g|4c16g(默认: 2c8g
--root PATH 安装目录(默认: /opt/nexus
--skip-clone 已在 /opt/nexus,不重新 clone
--skip-1panel-check 不检测 1Panel 是否已安装
-h, --help 显示帮助
安装后请用浏览器打开: https://域名/app/install.html
root 下全局命令: nexus-fresh | nexus-update | nx
EOF
}
SKIP_1PANEL_CHECK=false
SKIP_CLONE=false
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help) usage; exit 0 ;;
--domain) NEXUS_DOMAIN="$2"; shift 2 ;;
--profile) NEXUS_PROFILE="$2"; shift 2 ;;
--root) NEXUS_ROOT="$2"; shift 2 ;;
--skip-clone) SKIP_CLONE=true; shift ;;
--skip-1panel-check) SKIP_1PANEL_CHECK=true; shift ;;
*) error "未知参数: $1"; usage; exit 1 ;;
esac
done
banner() {
echo ""
echo -e "${BLUE}╔══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}${NC} Nexus 6.0 — 全新安装(1Panel + Docker Compose ${BLUE}${NC}"
echo -e "${BLUE}${NC} 域名: ${NEXUS_DOMAIN} ${BLUE}${NC}"
echo -e "${BLUE}${NC} 档位: ${NEXUS_PROFILE} 目录: ${NEXUS_ROOT} ${BLUE}${NC}"
echo -e "${BLUE}╚══════════════════════════════════════════════════════════════╝${NC}"
echo ""
}
load_credentials() {
step "加载凭据..."
local f
for f in /root/.nexus-deploy.env /root/.nexus-secrets/nexus.env; do
if [[ -f "$f" ]]; then
# shellcheck disable=SC1090
set -a
source "$f"
set +a
info "已加载 $f"
fi
done
if [[ -f "${NEXUS_ROOT}/deploy/nexus-1panel.secrets.sh" ]]; then
# shellcheck disable=SC1090
set -a
source "${NEXUS_ROOT}/deploy/nexus-1panel.secrets.sh"
set +a
info "已加载 ${NEXUS_ROOT}/deploy/nexus-1panel.secrets.sh(可选)"
fi
unset NEXUS_SECRET_KEY NEXUS_API_KEY NEXUS_ENCRYPTION_KEY
info "全新安装:NEXUS 密钥将在 docker/.env.prod 中按本机自动生成"
}
install_root_commands() {
[[ -d "${NEXUS_ROOT}/deploy" ]] || return 0
NEXUS_ROOT="$NEXUS_ROOT" bash "${NEXUS_ROOT}/deploy/install-nx-cli.sh" || true
info "全局命令: nx · nexus-update · nexus-fresh · nexus-install · nexus-1panel"
}
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 # 统一菜单(一键更新 / 重启 / 日志) ${GREEN}${NC}"
echo -e "${GREEN}${NC} nexus-update # 等同 deploy/update.sh ${GREEN}${NC}"
echo -e "${GREEN}╚══════════════════════════════════════════════════════════════╝${NC}"
echo ""
}
warn_if_already_installed() {
local env_prod="${NEXUS_ROOT}/docker/.env.prod" cname
[[ -f "$env_prod" ]] || return 0
cname="$(docker ps --format '{{.Names}}' 2>/dev/null | grep -E 'nexus-prod-nexus|nexus-nexus-1' | head -1 || true)"
if [[ -n "$cname" ]] && docker exec "$cname" test -f /var/lib/nexus/.install_locked 2>/dev/null; then
warn "检测到已安装并锁定的 Nexus(将清除 nexus-state 卷内配置并重建)"
read -r -p "确认继续全新安装? [y/N]: " ok
[[ "$ok" == "y" || "$ok" == "Y" ]] || exit 0
fi
}
main() {
banner
if [[ "$SKIP_CLONE" == true && -d "${NEXUS_ROOT}/deploy" ]]; then
install_root_commands
fi
warn_if_already_installed
phase_preflight
phase_1panel
phase_packages
phase_clone
phase_install_stack
phase_post
}
main "$@"