fix(deploy): auto-remove legacy Compose MySQL containers on upgrade

Run uninstall-mysql-compose before install/upgrade and pass --remove-orphans so nexus-prod mysql orphans are stopped after the service is dropped from compose.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Nexus Deploy
2026-06-06 03:32:00 +08:00
parent f37ebf8621
commit 1bd69077a2
4 changed files with 55 additions and 14 deletions
+18 -3
View File
@@ -537,12 +537,26 @@ write_env_prod() {
info "已写入 $env_file"
}
purge_legacy_bundled_services() {
local root="$1"
local s
for s in \
"$root/deploy/uninstall-mysql-compose.sh" \
"$root/deploy/uninstall-redis-compose.sh"; do
if [[ -x "$s" ]]; then
step "清理遗留 Compose 内置服务: $(basename "$s")"
NEXUS_ROOT="$root" bash "$s" || true
fi
done
}
compose_up() {
local root="$1"
save_host_profile "$root"
purge_legacy_bundled_services "$root"
info "档位: ${NEXUS_PROFILE}(仅 Nexus 容器;MySQL/Redis 请自行安装)"
info "构建并启动(首次约 1020 分钟)..."
compose_cmd "$root" up -d --build
compose_cmd "$root" up -d --build --remove-orphans
}
verify_install_wizard() {
@@ -772,8 +786,9 @@ cmd_upgrade() {
git_upgrade
apply_pool_to_env_prod "$NEXUS_ROOT" "$(profile_env_file "$NEXUS_ROOT")"
save_host_profile "$NEXUS_ROOT"
step "重建容器..."
compose_cmd "$NEXUS_ROOT" up -d --build
purge_legacy_bundled_services "$NEXUS_ROOT"
step "重建容器(--remove-orphans 清理旧 mysql/redis..."
compose_cmd "$NEXUS_ROOT" up -d --build --remove-orphans
if [[ "$PRUNE_IMAGES" == true ]]; then
docker image prune -f >/dev/null 2>&1 || true
fi
+2 -2
View File
@@ -185,7 +185,7 @@ god_stop_stack() {
}
god_start_stack() {
compose_cmd "$NEXUS_ROOT" up -d
compose_cmd "$NEXUS_ROOT" up -d --remove-orphans
verify_health "$NEXUS_ROOT" "启动" || true
}
@@ -272,7 +272,7 @@ EOF
3) god_start_stack; pause_enter ;;
4) god_stop_stack; pause_enter ;;
5)
compose_cmd "$NEXUS_ROOT" up -d --build nexus
compose_cmd "$NEXUS_ROOT" up -d --build --remove-orphans nexus
verify_health "$NEXUS_ROOT" "重建" || true
pause_enter
;;
+29 -9
View File
@@ -33,6 +33,17 @@ usage() {
EOF
}
compose_env_args() {
local_env=()
[[ -f "${NEXUS_ROOT}/docker/.env.prod" ]] && local_env+=(--env-file "${NEXUS_ROOT}/docker/.env.prod")
local prof="${NEXUS_ROOT}/docker/.host-profile"
if [[ -f "$prof" ]]; then
local p
p="$(tr -d '\r\n' <"$prof")"
[[ -f "${NEXUS_ROOT}/docker/profiles/${p}.env" ]] && local_env+=(--env-file "${NEXUS_ROOT}/docker/profiles/${p}.env")
fi
}
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help) usage; exit 0 ;;
@@ -50,7 +61,7 @@ stop_rm_container() {
if docker ps -a --format '{{.Names}}' | grep -qx "$name"; then
info "停止并删除容器: $name"
docker stop "$name" >/dev/null 2>&1 || true
docker rm "$name" >/dev/null 2>&1 || true
docker rm -f "$name" >/dev/null 2>&1 || true
removed=$((removed + 1))
fi
}
@@ -64,18 +75,19 @@ while IFS= read -r c; do
stop_rm_container "$c"
done < <(docker ps -a --format '{{.Names}}' | grep -iE 'nexus.*mysql|mysql.*nexus' || true)
compose_env_args
if [[ -f "${NEXUS_ROOT}/${COMPOSE_FILE}" ]] && grep -q '^ mysql:' "${NEXUS_ROOT}/${COMPOSE_FILE}" 2>/dev/null; then
warn "compose 仍含 mysql 服务,尝试 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 mysql 2>/dev/null || true)
(cd "$NEXUS_ROOT" && docker compose -f "$COMPOSE_FILE" "${local_env[@]}" rm -f mysql 2>/dev/null || true)
removed=$((removed + 1))
elif [[ -f "${NEXUS_ROOT}/${COMPOSE_FILE}" && -f "${NEXUS_ROOT}/docker/.env.prod" ]]; then
info "Compose --remove-orphans(从 nexus-prod 项目移除 mysql 孤儿容器)..."
(cd "$NEXUS_ROOT" && docker compose -f "$COMPOSE_FILE" "${local_env[@]}" up -d --remove-orphans 2>/dev/null || true)
while IFS= read -r c; do
[[ -z "$c" ]] && continue
stop_rm_container "$c"
done < <(docker ps -a --format '{{.Names}}' | grep -iE 'nexus.*mysql|mysql.*nexus' || true)
fi
if [[ "$PURGE_VOLUME" == true ]]; then
@@ -86,11 +98,19 @@ if [[ "$PURGE_VOLUME" == true ]]; then
done < <(docker volume ls -q | grep -iE 'nexus.*mysql|mysql.*nexus' || true)
fi
if [[ "$removed" -gt 0 ]]; then
leftover="$(docker ps -a --format '{{.Names}}' | grep -iE 'nexus.*mysql|mysql.*nexus' || true)"
if [[ -n "$leftover" ]]; then
warn "仍有 MySQL 相关容器:"
echo "$leftover" | sed 's/^/ /'
warn "若确认为 Compose 遗留,可: docker rm -f <容器名>"
elif [[ "$removed" -gt 0 ]]; then
info "Compose MySQL 容器已卸载。"
else
info "未发现 Nexus Compose MySQL 容器。"
fi
echo ""
info "当前 Nexus 栈:"
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}' | grep -i nexus || docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
echo ""
info "下一步:自建 MySQL 数据库与用户,安装向导步骤 3 使用 host.docker.internal:3306"
@@ -40,3 +40,9 @@ bash deploy/sync-install-wizard-to-container.sh
- `docker compose -f docker/docker-compose.prod.yml config` 仅含 `nexus` 服务
- `python3 scripts/generate_nexus_secrets.py write-prod --fresh` 输出无 `MYSQL_*`
- 安装向导步骤 3 可连接外置 MySQL 并完成 `init-db`
- `docker ps``nexus-prod-mysql-*``nexus-1panel.sh upgrade` 自动 `--remove-orphans`
## 2026-06-04 补充
- `install` / `upgrade` 前自动执行 `uninstall-mysql-compose.sh`
- `compose up` 增加 `--remove-orphans`,从 `nexus-prod` 项目移除已删服务的孤儿容器