From e42dc77127b4577306293cb6afe2a264684cca5a Mon Sep 17 00:00:00 2001 From: Nexus Deploy Date: Sat, 6 Jun 2026 02:51:52 +0800 Subject: [PATCH] feat(deploy): add redis compose uninstall; require Redis in install wizard Step 2 blocks until Redis connects; uninstall-redis-compose.sh removes legacy nexus-prod-redis container without touching host/1Panel Redis. Co-authored-by: Cursor --- deploy/README-1panel.md | 9 +- deploy/install-nexus-fresh.sh | 6 +- deploy/uninstall-redis-compose.sh | 116 ++++++++++++++++++ ...6-06-05-redis-required-uninstall-script.md | 26 ++++ server/api/install.py | 19 +-- web/app/install.html | 5 +- 6 files changed, 169 insertions(+), 12 deletions(-) create mode 100644 deploy/uninstall-redis-compose.sh create mode 100644 docs/changelog/2026-06-05-redis-required-uninstall-script.md diff --git a/deploy/README-1panel.md b/deploy/README-1panel.md index 06a1785e..bdf8731d 100644 --- a/deploy/README-1panel.md +++ b/deploy/README-1panel.md @@ -32,7 +32,14 @@ curl -fsSL "http://66.154.115.8:3000/admin/Nexus/raw/branch/main/deploy/quick-in Docker 栈仅含 **MySQL + Nexus**。Redis 请在宿主机或 1Panel 应用商店单独安装,监听 `127.0.0.1:6379`(或改 `docker/.env.prod` 的 `NEXUS_REDIS_URL`)。 -安装向导步骤 3:Docker 部署时 Redis 主机填 **`host.docker.internal`**,端口 `6379`。 +安装向导步骤 2:**必须先连通 Redis** 才能进入步骤 3。步骤 3 Redis 主机填 **`host.docker.internal`**,端口 `6379`。 + +卸载旧 Compose Redis 容器: + +```bash +bash /opt/nexus/deploy/uninstall-redis-compose.sh +bash /opt/nexus/deploy/uninstall-redis-compose.sh --purge-volume # 连数据卷一并删除 +``` ## 1Panel 反代(必须在面板 UI 操作) diff --git a/deploy/install-nexus-fresh.sh b/deploy/install-nexus-fresh.sh index d2e6f8f1..4150114e 100644 --- a/deploy/install-nexus-fresh.sh +++ b/deploy/install-nexus-fresh.sh @@ -123,7 +123,8 @@ install_root_commands() { chmod +x "${NEXUS_ROOT}/deploy/nx" \ "${NEXUS_ROOT}/deploy/install-nexus-fresh.sh" \ "${NEXUS_ROOT}/deploy/nexus-1panel.sh" \ - "${NEXUS_ROOT}/deploy/sync-install-wizard-to-container.sh" 2>/dev/null || true + "${NEXUS_ROOT}/deploy/sync-install-wizard-to-container.sh" \ + "${NEXUS_ROOT}/deploy/uninstall-redis-compose.sh" 2>/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 @@ -132,7 +133,8 @@ install_root_commands() { info "已注册全局命令(root 直接输入即可):" info " nexus-1panel-docker — 重装服务器(1Panel + Docker + Nexus)" info " nexus-install — 仅 Nexus Docker(curl 入口)" - info " nx — 主菜单 / 上帝菜单" + info " nexus-1panel — 底层 install/upgrade 脚本" + info " nx — 主菜单 / nx god 上帝菜单" info " nexus-fresh — 全新安装脚本" } diff --git a/deploy/uninstall-redis-compose.sh b/deploy/uninstall-redis-compose.sh new file mode 100644 index 00000000..44eda6f4 --- /dev/null +++ b/deploy/uninstall-redis-compose.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +# ============================================================================= +# 卸载 Nexus 旧版 Compose 内置 Redis 容器 +# +# 适用:已从 docker-compose.prod.yml 移除 redis 服务,改用宿主机/1Panel 自建 Redis。 +# 不会卸载 apt/1Panel 安装的 Redis,仅删除 Docker 容器与(可选)数据卷。 +# +# bash deploy/uninstall-redis-compose.sh +# bash deploy/uninstall-redis-compose.sh --purge-volume # 同时删 redis-data 卷 +# ============================================================================= + +set -euo pipefail + +NEXUS_ROOT="${NEXUS_ROOT:-/opt/nexus}" +COMPOSE_FILE="${COMPOSE_FILE:-docker/docker-compose.prod.yml}" +PURGE_VOLUME=false + +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} $*" >&2; } + +usage() { + cat </dev/null 2>&1 || true + docker rm "$name" >/dev/null 2>&1 || true + removed=$((removed + 1)) + fi +} + +# 常见 Compose 命名 +for pattern in nexus-prod-redis-1 nexus-prod-redis nexus-redis-1; do + stop_rm_container "$pattern" +done + +# 名称含 nexus 且含 redis 的容器 +while IFS= read -r c; do + [[ -z "$c" ]] && continue + stop_rm_container "$c" +done < <(docker ps -a --format '{{.Names}}' | grep -iE 'nexus.*redis|redis.*nexus' || true) + +# 若旧 compose 仍定义 redis 服务 +if [[ -f "${NEXUS_ROOT}/${COMPOSE_FILE}" ]]; then + if grep -q '^ redis:' "${NEXUS_ROOT}/${COMPOSE_FILE}" 2>/dev/null; then + warn "compose 仍含 redis 服务,尝试 compose rm..." + local_env=() + [[ -f "${NEXUS_ROOT}/docker/.env.prod" ]] && local_env+=(--env-file "${NEXUS_ROOT}/docker/.env.prod") + prof="${NEXUS_ROOT}/docker/.host-profile" + if [[ -f "$prof" ]]; then + p="$(tr -d '\r\n' <"$prof")" + [[ -f "${NEXUS_ROOT}/docker/profiles/${p}.env" ]] && local_env+=(--env-file "${NEXUS_ROOT}/docker/profiles/${p}.env") + fi + (cd "$NEXUS_ROOT" && docker compose -f "$COMPOSE_FILE" "${local_env[@]}" stop redis 2>/dev/null || true) + (cd "$NEXUS_ROOT" && docker compose -f "$COMPOSE_FILE" "${local_env[@]}" rm -f redis 2>/dev/null || true) + removed=$((removed + 1)) + fi +fi + +if [[ "$PURGE_VOLUME" == true ]]; then + while IFS= read -r vol; do + [[ -z "$vol" ]] && continue + info "删除数据卷: $vol" + docker volume rm "$vol" 2>/dev/null || warn "无法删除卷 $vol(可能被占用)" + done < <(docker volume ls -q | grep -iE 'nexus.*redis|redis.*nexus' || true) +fi + +echo "" +if [[ "$removed" -gt 0 ]]; then + info "Compose Redis 容器已卸载。" +else + info "未发现 Nexus Compose Redis 容器(可能已删除)。" +fi + +echo "" +info "下一步:在宿主机或 1Panel 安装 Redis,确认监听 6379:" +echo " apt install -y redis-server && systemctl enable --now redis-server" +echo " redis-cli ping # 期望 PONG" +echo "" +info "Docker 内 Nexus 连接宿主机 Redis:安装向导 / .env 使用 host.docker.internal:6379" diff --git a/docs/changelog/2026-06-05-redis-required-uninstall-script.md b/docs/changelog/2026-06-05-redis-required-uninstall-script.md new file mode 100644 index 00000000..7645a3e3 --- /dev/null +++ b/docs/changelog/2026-06-05-redis-required-uninstall-script.md @@ -0,0 +1,26 @@ +# 2026-06-05 — Redis 强制连通 + Compose Redis 卸载脚本 + +## 摘要 + +- 恢复安装向导步骤 2:**Redis 未连接则不可进入步骤 3** +- 新增 `deploy/uninstall-redis-compose.sh` 卸载遗留 `nexus-prod-redis` 容器 + +## 动机 + +用户自行安装 Redis,但环境检测必须验证连通;旧 Compose Redis 容器需单独卸载。 + +## 涉及文件 + +- `server/api/install.py` — Redis `pass: redis_ok` +- `web/app/install.html` — 步骤 2「下一步」在 `!envAllPass` 时禁用 +- `deploy/uninstall-redis-compose.sh` — 新脚本 +- `deploy/README-1panel.md` — 文档 + +## 服务器操作 + +```bash +cd /opt/nexus && git pull +bash deploy/uninstall-redis-compose.sh +apt install -y redis-server && systemctl enable --now redis-server +bash deploy/sync-install-wizard-to-container.sh +``` diff --git a/server/api/install.py b/server/api/install.py index 43fb3978..c788ebb0 100644 --- a/server/api/install.py +++ b/server/api/install.py @@ -99,7 +99,7 @@ def _build_redis_url(req: InitDbRequest) -> str: def _resolve_redis_probe() -> tuple[str, int, str | None]: - """Redis target for install wizard health check (Docker uses redis:6379, not host loopback).""" + """Redis target for install wizard (Docker: host.docker.internal → 宿主机自建 Redis).""" url = os.environ.get("NEXUS_REDIS_URL", "").strip() if url: parsed = urlparse(url) @@ -442,9 +442,9 @@ async def env_check(): "pass": False, }) - # Redis — 用户自行安装(1Panel/宿主机),不阻塞安装向导 + # Redis — 须先安装并连通(宿主机/1Panel);Docker 默认 host.docker.internal:6379 redis_ok = False - redis_msg = "未检测" + redis_msg = "未连接" rh, rp, rpass = _resolve_redis_probe() redis_label = f"{rh}:{rp}" try: @@ -454,20 +454,23 @@ async def env_check(): host=rh, port=rp, password=rpass or None, - socket_timeout=0.5, + socket_timeout=2.0, ) r.ping() redis_ok = True redis_msg = f"✓ 已连接 {redis_label}" except Exception as e: - redis_msg = f"未连接 {redis_label}(可继续,步骤3配置或稍后安装 Redis)— {e}" + redis_msg = ( + f"连接失败: {e}(请先在宿主机/1Panel 安装 Redis;" + f"Docker 部署须监听宿主机 6379 且 NEXUS_REDIS_URL 指向 {redis_label})" + ) except ImportError: - redis_msg = "redis 库未安装(可继续)" + redis_msg = "redis 库未安装" checks.append({ "name": "Redis", - "required": "自行安装(步骤3配置)", + "required": "已连接", "current": redis_msg, - "pass": True, + "pass": redis_ok, }) # MySQL database — user configures in step 3 diff --git a/web/app/install.html b/web/app/install.html index 8439f786..37254b20 100644 --- a/web/app/install.html +++ b/web/app/install.html @@ -128,7 +128,10 @@
-