fix(deploy): 部署脚本自动识别 Docker 与 Supervisor 运行时
upgrade/deploy-production 等分流到 nexus-1panel upgrade;升级完成后提示安装 nx cron。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+70
-33
@@ -1,58 +1,95 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
# deploy-frontend.sh — Build Vuetify frontend and deploy to server
|
# deploy-frontend.sh — Build Vuetify frontend and deploy to server
|
||||||
#
|
#
|
||||||
|
# Docker 生产:前端在镜像内构建,远程执行 nexus-1panel.sh upgrade
|
||||||
|
# Supervisor:tar 上传到 web/app + supervisorctl restart
|
||||||
|
#
|
||||||
# Usage: bash deploy/deploy-frontend.sh
|
# Usage: bash deploy/deploy-frontend.sh
|
||||||
# Run from the Nexus project root directory.
|
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
NEXUS_SSH_HOST="${NEXUS_SSH:-nexus}"
|
||||||
|
SSH_OPTS=(-o BatchMode=yes -o ConnectTimeout=15)
|
||||||
|
if [[ -n "${NEXUS_SSH_KEY:-}" ]]; then
|
||||||
|
SSH_OPTS+=(-i "${NEXUS_SSH_KEY}")
|
||||||
|
fi
|
||||||
|
ssh_cmd() { ssh "${SSH_OPTS[@]}" "${NEXUS_SSH_HOST}" "$@"; }
|
||||||
|
|
||||||
echo "═══ Nexus Frontend Deploy ═══"
|
echo "═══ Nexus Frontend Deploy ═══"
|
||||||
|
|
||||||
# 1. Build
|
REMOTE_RUNTIME=$(ssh_cmd 'bash -s' <<'REMOTE'
|
||||||
echo "▶ Building frontend..."
|
set -euo pipefail
|
||||||
|
for d in /opt/nexus /www/wwwroot/api.synaglobal.vip; do
|
||||||
|
[[ -d "$d/server" ]] || continue
|
||||||
|
if [[ -f "$d/docker/.env.prod" ]] && docker compose version >/dev/null 2>&1; then
|
||||||
|
prof="$d/docker/.host-profile"
|
||||||
|
[[ -f "$prof" ]] || prof="$d/docker/profiles/2c8g.env"
|
||||||
|
if [[ -f "$prof" ]]; then
|
||||||
|
args=(-f "$d/docker/docker-compose.prod.yml")
|
||||||
|
docker network inspect 1panel-network >/dev/null 2>&1 && \
|
||||||
|
[[ -f "$d/docker/docker-compose.1panel.yml" ]] && \
|
||||||
|
args+=(-f "$d/docker/docker-compose.1panel.yml")
|
||||||
|
q=$(cd "$d" && docker compose "${args[@]}" \
|
||||||
|
--env-file "$d/docker/.env.prod" --env-file "$prof" ps -q nexus 2>/dev/null || true)
|
||||||
|
[[ -n "$q" ]] && echo "docker $d" && exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if command -v supervisorctl >/dev/null 2>&1 && supervisorctl status nexus >/dev/null 2>&1; then
|
||||||
|
echo "supervisor $d"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "unknown"
|
||||||
|
REMOTE
|
||||||
|
)
|
||||||
|
|
||||||
|
RUNTIME="${REMOTE_RUNTIME%% *}"
|
||||||
|
DEPLOY_PATH="${REMOTE_RUNTIME#* }"
|
||||||
|
[[ "$DEPLOY_PATH" == "$REMOTE_RUNTIME" ]] && DEPLOY_PATH="/www/wwwroot/api.synaglobal.vip"
|
||||||
|
|
||||||
|
echo "Remote runtime: ${RUNTIME} @ ${DEPLOY_PATH}"
|
||||||
|
|
||||||
|
echo "▶ Building frontend (local verify)..."
|
||||||
cd frontend && npx vite build && cd ..
|
cd frontend && npx vite build && cd ..
|
||||||
echo "✓ Build complete"
|
echo "✓ Build complete"
|
||||||
|
|
||||||
# 2. Tar the build output (index.html + assets/)
|
if [[ "$RUNTIME" == "docker" ]]; then
|
||||||
echo "▶ Packaging..."
|
echo "▶ Docker 生产:重建镜像以包含新前端(非 tar 热更新)..."
|
||||||
tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/
|
ssh_cmd "cd ${DEPLOY_PATH} && sudo env NEXUS_ROOT=${DEPLOY_PATH} bash ${DEPLOY_PATH}/deploy/nexus-1panel.sh upgrade"
|
||||||
echo "✓ Package ready ($(du -h /tmp/nexus-frontend.tar.gz | cut -f1))"
|
else
|
||||||
|
echo "▶ Packaging..."
|
||||||
|
tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/
|
||||||
|
echo "✓ Package ready ($(du -h /tmp/nexus-frontend.tar.gz | cut -f1))"
|
||||||
|
|
||||||
# 3. Upload to server
|
echo "▶ Uploading to server..."
|
||||||
echo "▶ Uploading to server..."
|
scp "${SSH_OPTS[@]}" /tmp/nexus-frontend.tar.gz "${NEXUS_SSH_HOST}:/tmp/nexus-frontend.tar.gz"
|
||||||
scp /tmp/nexus-frontend.tar.gz nexus:/tmp/nexus-frontend.tar.gz
|
echo "✓ Upload complete"
|
||||||
echo "✓ Upload complete"
|
|
||||||
|
|
||||||
# 4. Extract on server + prune orphaned legacy chunks
|
echo "▶ Deploying on server..."
|
||||||
echo "▶ Deploying on server..."
|
ssh_cmd "cd ${DEPLOY_PATH}/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz"
|
||||||
ssh nexus "cd /www/wwwroot/api.synaglobal.vip/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz"
|
echo "▶ Pruning orphaned assets..."
|
||||||
echo "▶ Pruning orphaned assets (dry-run first)..."
|
if ! ssh_cmd "python3 ${DEPLOY_PATH}/deploy/prune_frontend_assets.py --dry-run"; then
|
||||||
if ! ssh nexus "python3 /www/wwwroot/api.synaglobal.vip/deploy/prune_frontend_assets.py --dry-run"; then
|
echo "✗ Prune dry-run failed"
|
||||||
echo "✗ Prune dry-run failed — aborting (no files deleted)"
|
exit 1
|
||||||
exit 1
|
fi
|
||||||
|
ssh_cmd "python3 ${DEPLOY_PATH}/deploy/prune_frontend_assets.py"
|
||||||
|
echo "✓ Extracted and pruned"
|
||||||
|
|
||||||
|
echo "▶ Restarting backend..."
|
||||||
|
ssh_cmd "supervisorctl restart nexus"
|
||||||
|
echo "✓ Restarted"
|
||||||
fi
|
fi
|
||||||
if ! ssh nexus "python3 /www/wwwroot/api.synaglobal.vip/deploy/prune_frontend_assets.py"; then
|
|
||||||
echo "✗ Prune failed — check index.html references before retry"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "✓ Extracted and pruned"
|
|
||||||
|
|
||||||
# 5. Restart backend
|
|
||||||
echo "▶ Restarting backend..."
|
|
||||||
ssh nexus "supervisorctl restart nexus"
|
|
||||||
echo "✓ Restarted"
|
|
||||||
|
|
||||||
# 6. Health check
|
|
||||||
sleep 3
|
sleep 3
|
||||||
HEALTH=$(ssh nexus "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8600/health" 2>/dev/null || echo "000")
|
HEALTH=$(ssh_cmd "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8600/health" 2>/dev/null || echo "000")
|
||||||
SPA=$(ssh nexus "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8600/app/" 2>/dev/null || echo "000")
|
SPA=$(ssh_cmd "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8600/app/" 2>/dev/null || echo "000")
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "═══ Verification ═══"
|
echo "═══ Verification ═══"
|
||||||
echo " /health → $HEALTH"
|
echo " /health → $HEALTH"
|
||||||
echo " /app/ → $SPA"
|
echo " /app/ → $SPA"
|
||||||
|
|
||||||
if [ "$HEALTH" = "200" ] && [ "$SPA" = "200" ]; then
|
if [[ "$HEALTH" == "200" || "$HEALTH" == "ok" ]] && [[ "$SPA" == "200" ]]; then
|
||||||
echo "✓ Deploy successful!"
|
echo "✓ Deploy successful!"
|
||||||
else
|
else
|
||||||
echo "✗ Verification failed — check server logs"
|
echo "✗ Verification failed — check server logs"
|
||||||
|
|||||||
+32
-15
@@ -1,28 +1,44 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Run ON production server (宝塔终端 / ssh root@47.254.123.106)
|
# Run ON production server — 自动识别 Docker / Supervisor
|
||||||
# Pulls latest main from Gitea and restarts Nexus. Frontend tar must be uploaded separately
|
|
||||||
# if you did not build on this machine.
|
|
||||||
#
|
#
|
||||||
# Usage (on server):
|
# Usage (on server):
|
||||||
# cd /www/wwwroot/api.synaglobal.vip
|
# cd /opt/nexus && sudo bash deploy/deploy-on-server.sh
|
||||||
# bash deploy/deploy-on-server.sh
|
# cd /www/wwwroot/api.synaglobal.vip && bash deploy/deploy-on-server.sh
|
||||||
#
|
#
|
||||||
# Optional env:
|
# Optional env:
|
||||||
# NEXUS_GITEA_TOKEN — if git pull needs auth
|
# NEXUS_GITEA_TOKEN — if git pull needs auth
|
||||||
# SKIP_FRONTEND=1 — backend only
|
# SKIP_FRONTEND=1 — Supervisor 模式跳过热更新前端 tar
|
||||||
|
# NEXUS_DEPLOY_PATH — 覆盖自动检测路径
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
DEPLOY_PATH="${NEXUS_DEPLOY_PATH:-/www/wwwroot/api.synaglobal.vip}"
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
# shellcheck source=./detect_deploy_runtime.sh
|
||||||
|
source "${SCRIPT_DIR}/detect_deploy_runtime.sh"
|
||||||
|
|
||||||
|
DEPLOY_PATH="$(resolve_nexus_root "${NEXUS_DEPLOY_PATH:-}" 2>/dev/null || true)"
|
||||||
|
if [[ -z "$DEPLOY_PATH" ]]; then
|
||||||
|
echo "ERROR: cannot resolve Nexus root" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
cd "${DEPLOY_PATH}"
|
cd "${DEPLOY_PATH}"
|
||||||
|
|
||||||
echo "═══ Nexus server-side deploy ═══"
|
RUNTIME="$(detect_nexus_runtime "$DEPLOY_PATH")"
|
||||||
echo "Path: ${DEPLOY_PATH}"
|
PORT="$(nexus_publish_port_for "$DEPLOY_PATH")"
|
||||||
|
|
||||||
if [ -n "${NEXUS_GITEA_TOKEN:-}" ]; then
|
echo "═══ Nexus server-side deploy ═══"
|
||||||
|
echo "Path: ${DEPLOY_PATH}"
|
||||||
|
echo "Runtime: ${RUNTIME}"
|
||||||
|
|
||||||
|
if [[ -n "${NEXUS_GITEA_TOKEN:-}" ]]; then
|
||||||
git remote set-url origin "http://admin:${NEXUS_GITEA_TOKEN}@66.154.115.8:3000/admin/Nexus.git"
|
git remote set-url origin "http://admin:${NEXUS_GITEA_TOKEN}@66.154.115.8:3000/admin/Nexus.git"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$RUNTIME" == "docker" ]]; then
|
||||||
|
echo "▶ Docker upgrade (pull + rebuild)..."
|
||||||
|
exec env NEXUS_ROOT="$DEPLOY_PATH" bash "$DEPLOY_PATH/deploy/nexus-1panel.sh" upgrade
|
||||||
|
fi
|
||||||
|
|
||||||
echo "▶ git fetch + reset --hard origin/main..."
|
echo "▶ git fetch + reset --hard origin/main..."
|
||||||
git fetch --all
|
git fetch --all
|
||||||
git reset --hard origin/main
|
git reset --hard origin/main
|
||||||
@@ -31,11 +47,11 @@ echo " HEAD: $(git log -1 --oneline)"
|
|||||||
echo "▶ supervisorctl restart nexus..."
|
echo "▶ supervisorctl restart nexus..."
|
||||||
supervisorctl restart nexus
|
supervisorctl restart nexus
|
||||||
|
|
||||||
if [ -f /tmp/nexus-frontend.tar.gz ] && [ "${SKIP_FRONTEND:-0}" != "1" ]; then
|
if [[ -f /tmp/nexus-frontend.tar.gz && "${SKIP_FRONTEND:-0}" != "1" ]]; then
|
||||||
echo "▶ extract /tmp/nexus-frontend.tar.gz..."
|
echo "▶ extract /tmp/nexus-frontend.tar.gz..."
|
||||||
tar xzf /tmp/nexus-frontend.tar.gz -C web/app
|
tar xzf /tmp/nexus-frontend.tar.gz -C web/app
|
||||||
rm -f /tmp/nexus-frontend.tar.gz
|
rm -f /tmp/nexus-frontend.tar.gz
|
||||||
if [ -f deploy/prune_frontend_assets.py ]; then
|
if [[ -f deploy/prune_frontend_assets.py ]]; then
|
||||||
python3 deploy/prune_frontend_assets.py --dry-run
|
python3 deploy/prune_frontend_assets.py --dry-run
|
||||||
python3 deploy/prune_frontend_assets.py
|
python3 deploy/prune_frontend_assets.py
|
||||||
fi
|
fi
|
||||||
@@ -43,13 +59,14 @@ if [ -f /tmp/nexus-frontend.tar.gz ] && [ "${SKIP_FRONTEND:-0}" != "1" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
sleep 3
|
sleep 3
|
||||||
HEALTH=$(curl -s http://127.0.0.1:8600/health || true)
|
HEALTH=$(curl -s "http://127.0.0.1:${PORT}/health" || true)
|
||||||
SPA=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8600/app/ || echo "000")
|
SPA=$(curl -s -o /dev/null -w '%{http_code}' "http://127.0.0.1:${PORT}/app/" || echo "000")
|
||||||
echo " /health → ${HEALTH}"
|
echo " /health → ${HEALTH}"
|
||||||
echo " /app/ → ${SPA}"
|
echo " /app/ → ${SPA}"
|
||||||
|
|
||||||
if [ "${HEALTH}" = "ok" ] && [ "${SPA}" = "200" ]; then
|
if [[ "${HEALTH}" == "ok" && "${SPA}" == "200" ]]; then
|
||||||
echo "✓ Server deploy OK"
|
echo "✓ Server deploy OK"
|
||||||
|
suggest_ops_cron "$DEPLOY_PATH"
|
||||||
else
|
else
|
||||||
echo "✗ Verify failed — check: supervisorctl status nexus" >&2
|
echo "✗ Verify failed — check: supervisorctl status nexus" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
+74
-22
@@ -1,14 +1,14 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Full production deploy: push (optional) + backend pull + frontend tar + health
|
# Full production deploy: push (optional) + backend upgrade + frontend + health
|
||||||
|
#
|
||||||
|
# 自动识别远程 Docker(/opt/nexus)或 Supervisor(/www/wwwroot/...)运行时。
|
||||||
#
|
#
|
||||||
# Prerequisites on YOUR machine:
|
# Prerequisites on YOUR machine:
|
||||||
# - SSH: ~/.ssh/config Host nexus OR export NEXUS_SSH="root@47.254.123.106"
|
# - SSH: ~/.ssh/config Host nexus OR export NEXUS_SSH="azureuser@20.24.218.235"
|
||||||
# - Key: export NEXUS_SSH_KEY=~/.ssh/id_rsa_nexus
|
# - Key: export NEXUS_SSH_KEY=~/.ssh/id_rsa_nexus
|
||||||
# - Gitea push access for origin main
|
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# cd "$NEXUS_ROOT"
|
# cd "$NEXUS_ROOT"
|
||||||
# git add ... && git commit ... && git push origin main # if not pushed yet
|
|
||||||
# bash deploy/pre_deploy_check.sh
|
# bash deploy/pre_deploy_check.sh
|
||||||
# bash deploy/deploy-production.sh
|
# bash deploy/deploy-production.sh
|
||||||
|
|
||||||
@@ -19,17 +19,14 @@ cd "${ROOT}"
|
|||||||
|
|
||||||
NEXUS_SSH_HOST="${NEXUS_SSH:-nexus}"
|
NEXUS_SSH_HOST="${NEXUS_SSH:-nexus}"
|
||||||
SSH_OPTS=(-o BatchMode=yes -o ConnectTimeout=15)
|
SSH_OPTS=(-o BatchMode=yes -o ConnectTimeout=15)
|
||||||
if [ -n "${NEXUS_SSH_KEY:-}" ]; then
|
if [[ -n "${NEXUS_SSH_KEY:-}" ]]; then
|
||||||
SSH_OPTS+=(-i "${NEXUS_SSH_KEY}")
|
SSH_OPTS+=(-i "${NEXUS_SSH_KEY}")
|
||||||
fi
|
fi
|
||||||
ssh_cmd() { ssh "${SSH_OPTS[@]}" "${NEXUS_SSH_HOST}" "$@"; }
|
ssh_cmd() { ssh "${SSH_OPTS[@]}" "${NEXUS_SSH_HOST}" "$@"; }
|
||||||
scp_cmd() { scp "${SSH_OPTS[@]}" "$@"; }
|
scp_cmd() { scp "${SSH_OPTS[@]}" "$@"; }
|
||||||
|
|
||||||
DEPLOY_PATH="${NEXUS_DEPLOY_PATH:-/www/wwwroot/api.synaglobal.vip}"
|
|
||||||
|
|
||||||
echo "═══ Nexus production deploy ═══"
|
echo "═══ Nexus production deploy ═══"
|
||||||
echo "SSH target: ${NEXUS_SSH_HOST}"
|
echo "SSH target: ${NEXUS_SSH_HOST}"
|
||||||
echo "Deploy path: ${DEPLOY_PATH}"
|
|
||||||
|
|
||||||
if ! ssh_cmd "echo SSH OK" >/dev/null 2>&1; then
|
if ! ssh_cmd "echo SSH OK" >/dev/null 2>&1; then
|
||||||
echo "ERROR: Cannot SSH to ${NEXUS_SSH_HOST}" >&2
|
echo "ERROR: Cannot SSH to ${NEXUS_SSH_HOST}" >&2
|
||||||
@@ -37,27 +34,82 @@ if ! ssh_cmd "echo SSH OK" >/dev/null 2>&1; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "▶ Backend: git pull + restart..."
|
REMOTE_DETECT=$(ssh_cmd 'bash -s' <<'REMOTE'
|
||||||
ssh_cmd "cd ${DEPLOY_PATH} && git fetch --all && git reset --hard origin/main && supervisorctl restart nexus"
|
set -euo pipefail
|
||||||
|
for d in /opt/nexus /www/wwwroot/api.synaglobal.vip; do
|
||||||
|
[[ -d "$d/server" ]] || continue
|
||||||
|
echo "ROOT=$d"
|
||||||
|
if [[ -f "$d/docker/.env.prod" ]] && docker compose version >/dev/null 2>&1; then
|
||||||
|
prof="$d/docker/.host-profile"
|
||||||
|
[[ -f "$prof" ]] || prof="$d/docker/profiles/2c8g.env"
|
||||||
|
if [[ -f "$prof" ]]; then
|
||||||
|
args=(-f "$d/docker/docker-compose.prod.yml")
|
||||||
|
docker network inspect 1panel-network >/dev/null 2>&1 && \
|
||||||
|
[[ -f "$d/docker/docker-compose.1panel.yml" ]] && \
|
||||||
|
args+=(-f "$d/docker/docker-compose.1panel.yml")
|
||||||
|
q=$(cd "$d" && docker compose "${args[@]}" \
|
||||||
|
--env-file "$d/docker/.env.prod" --env-file "$prof" ps -q nexus 2>/dev/null || true)
|
||||||
|
[[ -n "$q" ]] && echo RUNTIME=docker && exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if command -v supervisorctl >/dev/null 2>&1 && supervisorctl status nexus >/dev/null 2>&1; then
|
||||||
|
echo RUNTIME=supervisor
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo RUNTIME=unknown
|
||||||
|
exit 0
|
||||||
|
done
|
||||||
|
echo RUNTIME=none
|
||||||
|
REMOTE
|
||||||
|
)
|
||||||
|
|
||||||
echo "▶ Frontend: build + upload..."
|
DEPLOY_PATH="${NEXUS_DEPLOY_PATH:-$(echo "$REMOTE_DETECT" | sed -n 's/^ROOT=//p' | head -1)}"
|
||||||
cd frontend && npx vite build && cd ..
|
RUNTIME="$(echo "$REMOTE_DETECT" | sed -n 's/^RUNTIME=//p' | head -1)"
|
||||||
tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/
|
|
||||||
scp_cmd /tmp/nexus-frontend.tar.gz "${NEXUS_SSH_HOST}:/tmp/nexus-frontend.tar.gz"
|
if [[ -z "$DEPLOY_PATH" ]]; then
|
||||||
ssh_cmd "cd ${DEPLOY_PATH}/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz"
|
DEPLOY_PATH="${NEXUS_DEPLOY_PATH:-/opt/nexus}"
|
||||||
if ssh_cmd "test -f ${DEPLOY_PATH}/deploy/prune_frontend_assets.py"; then
|
fi
|
||||||
ssh_cmd "python3 ${DEPLOY_PATH}/deploy/prune_frontend_assets.py --dry-run"
|
if [[ -z "$RUNTIME" || "$RUNTIME" == "none" ]]; then
|
||||||
ssh_cmd "python3 ${DEPLOY_PATH}/deploy/prune_frontend_assets.py"
|
RUNTIME="unknown"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Deploy path: ${DEPLOY_PATH}"
|
||||||
|
echo "Runtime: ${RUNTIME}"
|
||||||
|
|
||||||
|
if [[ "$RUNTIME" == "docker" ]]; then
|
||||||
|
echo "▶ Docker: git pull + 镜像重建(前端在镜像内 vite build)..."
|
||||||
|
ssh_cmd "cd ${DEPLOY_PATH} && sudo git fetch --all && sudo git reset --hard origin/main && \
|
||||||
|
sudo env NEXUS_ROOT=${DEPLOY_PATH} bash ${DEPLOY_PATH}/deploy/nexus-1panel.sh upgrade"
|
||||||
|
elif [[ "$RUNTIME" == "supervisor" ]]; then
|
||||||
|
echo "▶ Supervisor: git pull + restart..."
|
||||||
|
ssh_cmd "cd ${DEPLOY_PATH} && git fetch --all && git reset --hard origin/main && supervisorctl restart nexus"
|
||||||
|
|
||||||
|
echo "▶ Frontend: build + upload..."
|
||||||
|
cd frontend && npx vite build && cd ..
|
||||||
|
tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/
|
||||||
|
scp_cmd /tmp/nexus-frontend.tar.gz "${NEXUS_SSH_HOST}:/tmp/nexus-frontend.tar.gz"
|
||||||
|
ssh_cmd "cd ${DEPLOY_PATH}/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz"
|
||||||
|
if ssh_cmd "test -f ${DEPLOY_PATH}/deploy/prune_frontend_assets.py"; then
|
||||||
|
ssh_cmd "python3 ${DEPLOY_PATH}/deploy/prune_frontend_assets.py --dry-run"
|
||||||
|
ssh_cmd "python3 ${DEPLOY_PATH}/deploy/prune_frontend_assets.py"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "ERROR: 无法识别远程运行时(非 Docker 也非 Supervisor)" >&2
|
||||||
|
echo " 请手动: ssh ${NEXUS_SSH_HOST} 'sudo nx update'" >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sleep 3
|
sleep 3
|
||||||
HEALTH=$(ssh_cmd "curl -s http://127.0.0.1:8600/health" 2>/dev/null || true)
|
PORT="$(ssh_cmd "grep -E '^NEXUS_PUBLISH_PORT=' ${DEPLOY_PATH}/docker/.env.prod 2>/dev/null | cut -d= -f2 | tr -d '\"' || echo 8600")"
|
||||||
SPA=$(ssh_cmd "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8600/app/" 2>/dev/null || echo "000")
|
HEALTH=$(ssh_cmd "curl -s http://127.0.0.1:${PORT}/health" 2>/dev/null || true)
|
||||||
|
SPA=$(ssh_cmd "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:${PORT}/app/" 2>/dev/null || echo "000")
|
||||||
echo " /health → ${HEALTH}"
|
echo " /health → ${HEALTH}"
|
||||||
echo " /app/ → ${SPA}"
|
echo " /app/ → ${SPA}"
|
||||||
if [ "${HEALTH}" = "ok" ] && [ "${SPA}" = "200" ]; then
|
if [[ "${HEALTH}" == "ok" && "${SPA}" == "200" ]]; then
|
||||||
echo "✓ Deploy successful"
|
echo "✓ Deploy successful"
|
||||||
|
ssh_cmd "command -v crontab >/dev/null && crontab -l 2>/dev/null | grep -q nexus-health-monitor" 2>/dev/null || \
|
||||||
|
echo " 提示: 远程未安装巡检 cron,可在服务器执行 sudo nx cron"
|
||||||
else
|
else
|
||||||
echo "✗ Verification failed — check supervisor logs on server" >&2
|
echo "✗ Verification failed — check logs on server" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Nexus — 部署运行时检测(Docker 1Panel / Supervisor 裸机)
|
||||||
|
#
|
||||||
|
# source deploy/detect_deploy_runtime.sh
|
||||||
|
# ROOT="$(resolve_nexus_root)"
|
||||||
|
# RUNTIME="$(detect_nexus_runtime "$ROOT")" # docker | supervisor | unknown
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
_COMPOSE_FILE="docker/docker-compose.prod.yml"
|
||||||
|
_COMPOSE_1PANEL="docker/docker-compose.1panel.yml"
|
||||||
|
_ENV_PROD="docker/.env.prod"
|
||||||
|
|
||||||
|
resolve_nexus_root() {
|
||||||
|
local hint="${1:-}"
|
||||||
|
if [[ -n "$hint" && -d "$hint/server" ]]; then
|
||||||
|
echo "$hint"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ -n "${NEXUS_ROOT:-}" && -d "${NEXUS_ROOT}/server" ]]; then
|
||||||
|
echo "$NEXUS_ROOT"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ -n "${NEXUS_DEPLOY_PATH:-}" && -d "${NEXUS_DEPLOY_PATH}/server" ]]; then
|
||||||
|
echo "$NEXUS_DEPLOY_PATH"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
local d
|
||||||
|
for d in /opt/nexus /www/wwwroot/api.synaglobal.vip; do
|
||||||
|
if [[ -d "$d/server" ]]; then
|
||||||
|
echo "$d"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
for d in /www/wwwroot/*/; do
|
||||||
|
[[ -d "${d}server" ]] || continue
|
||||||
|
echo "${d%/}"
|
||||||
|
return 0
|
||||||
|
done
|
||||||
|
if command -v supervisorctl >/dev/null 2>&1; then
|
||||||
|
local cwd
|
||||||
|
cwd="$(supervisorctl status nexus 2>/dev/null | grep -oP 'cwd=\K[^ ,]+' || true)"
|
||||||
|
if [[ -n "$cwd" && -d "$cwd/server" ]]; then
|
||||||
|
echo "$cwd"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_has_1panel_network() {
|
||||||
|
docker network inspect 1panel-network >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_nexus_runtime() {
|
||||||
|
local root="$1"
|
||||||
|
if [[ -f "$root/$_ENV_PROD" ]] && command -v docker >/dev/null 2>&1 \
|
||||||
|
&& docker compose version >/dev/null 2>&1; then
|
||||||
|
local -a args=(-f "$root/$_COMPOSE_FILE")
|
||||||
|
if _has_1panel_network && [[ -f "$root/$_COMPOSE_1PANEL" ]]; then
|
||||||
|
args+=(-f "$root/$_COMPOSE_1PANEL")
|
||||||
|
fi
|
||||||
|
local prof q
|
||||||
|
prof="$root/docker/.host-profile"
|
||||||
|
[[ -f "$prof" ]] || prof="$root/docker/profiles/2c8g.env"
|
||||||
|
if [[ -f "$prof" ]]; then
|
||||||
|
q="$(cd "$root" && docker compose "${args[@]}" \
|
||||||
|
--env-file "$root/$_ENV_PROD" --env-file "$prof" \
|
||||||
|
ps -q nexus 2>/dev/null || true)"
|
||||||
|
if [[ -n "$q" ]]; then
|
||||||
|
echo docker
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if command -v supervisorctl >/dev/null 2>&1 \
|
||||||
|
&& supervisorctl status nexus >/dev/null 2>&1; then
|
||||||
|
echo supervisor
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
nexus_publish_port_for() {
|
||||||
|
local root="$1"
|
||||||
|
local port
|
||||||
|
port="$(grep -E '^NEXUS_PUBLISH_PORT=' "$root/$_ENV_PROD" 2>/dev/null | head -1 | cut -d= -f2- | tr -d '\r" ' || true)"
|
||||||
|
if [[ -z "$port" && -f "$root/.env" ]]; then
|
||||||
|
port="$(grep -E '^NEXUS_PORT=' "$root/.env" 2>/dev/null | head -1 | cut -d= -f2- | tr -d '\r" ' || true)"
|
||||||
|
fi
|
||||||
|
echo "${port:-8600}"
|
||||||
|
}
|
||||||
|
|
||||||
|
nexus_restart_service() {
|
||||||
|
local root="$1"
|
||||||
|
local runtime
|
||||||
|
runtime="$(detect_nexus_runtime "$root")"
|
||||||
|
case "$runtime" in
|
||||||
|
docker)
|
||||||
|
local cname
|
||||||
|
cname="$(docker ps --format '{{.Names}}' 2>/dev/null | grep -E 'nexus-prod-nexus|nexus-nexus-1' | head -1 || true)"
|
||||||
|
if [[ -n "$cname" ]]; then
|
||||||
|
docker restart "$cname"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
supervisor)
|
||||||
|
supervisorctl restart nexus
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
nexus_has_ops_cron() {
|
||||||
|
command -v crontab >/dev/null 2>&1 \
|
||||||
|
&& crontab -l 2>/dev/null | grep -q 'nexus-health-monitor'
|
||||||
|
}
|
||||||
|
|
||||||
|
suggest_ops_cron() {
|
||||||
|
local root="$1"
|
||||||
|
if nexus_has_ops_cron; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "[WARN] 未检测到 health_monitor / db_backup cron"
|
||||||
|
echo " 建议: sudo bash ${root}/deploy/install_ops_cron.sh"
|
||||||
|
echo " 或: sudo nx cron"
|
||||||
|
}
|
||||||
@@ -1206,6 +1206,12 @@ cmd_upgrade() {
|
|||||||
rollback_compose_upgrade "$NEXUS_ROOT" || true
|
rollback_compose_upgrade "$NEXUS_ROOT" || true
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
# shellcheck source=./detect_deploy_runtime.sh
|
||||||
|
if [[ -f "$NEXUS_ROOT/deploy/detect_deploy_runtime.sh" ]]; then
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$NEXUS_ROOT/deploy/detect_deploy_runtime.sh"
|
||||||
|
suggest_ops_cron "$NEXUS_ROOT"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_check() {
|
cmd_check() {
|
||||||
|
|||||||
+49
-55
@@ -1,16 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
# ================================================================
|
# Nexus 6.0 — Upgrade Script(自动识别 Docker / Supervisor)
|
||||||
# Nexus 6.0 — Upgrade Script
|
|
||||||
#
|
#
|
||||||
# Usage:
|
# sudo bash deploy/upgrade.sh
|
||||||
# sudo bash upgrade.sh # auto-detect deploy dir
|
# sudo bash deploy/upgrade.sh --deploy-dir /opt/nexus
|
||||||
# sudo bash upgrade.sh --deploy-dir /opt/nexus # specify deploy dir
|
|
||||||
#
|
#
|
||||||
# Safe: git pull + pip install + restart. Database is NOT touched.
|
# Docker 1Panel:委托 deploy/nexus-1panel.sh upgrade(拉代码 + 备份 + 重建镜像)
|
||||||
# ================================================================
|
# Supervisor 裸机:git pull + venv pip + supervisorctl restart
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
# shellcheck source=./detect_deploy_runtime.sh
|
||||||
|
source "${SCRIPT_DIR}/detect_deploy_runtime.sh"
|
||||||
|
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
YELLOW='\033[1;33m'
|
YELLOW='\033[1;33m'
|
||||||
@@ -21,98 +22,90 @@ warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
|||||||
error() { echo -e "${RED}[ERROR]${NC} $*"; }
|
error() { echo -e "${RED}[ERROR]${NC} $*"; }
|
||||||
|
|
||||||
DEPLOY_DIR=""
|
DEPLOY_DIR=""
|
||||||
|
EXTRA_ARGS=()
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case $1 in
|
case "$1" in
|
||||||
--deploy-dir) DEPLOY_DIR="$2"; shift 2 ;;
|
--deploy-dir) DEPLOY_DIR="$2"; shift 2 ;;
|
||||||
|
--no-backup|--require-backup|--no-cache|--prune|--check|--dry-run)
|
||||||
|
EXTRA_ARGS+=("$1"); shift ;;
|
||||||
-h|--help)
|
-h|--help)
|
||||||
echo "Usage: sudo bash upgrade.sh [--deploy-dir PATH]"
|
cat <<'EOF'
|
||||||
exit 0 ;;
|
用法: sudo bash deploy/upgrade.sh [--deploy-dir PATH] [nexus-1panel 升级选项]
|
||||||
*) shift ;;
|
|
||||||
|
Docker 环境自动走 nexus-1panel.sh upgrade;Supervisor 环境走 venv + supervisorctl。
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*) EXTRA_ARGS+=("$1"); shift ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# Auto-detect deploy directory
|
if [[ -z "$DEPLOY_DIR" ]]; then
|
||||||
if [ -z "$DEPLOY_DIR" ]; then
|
DEPLOY_DIR="$(resolve_nexus_root 2>/dev/null || true)"
|
||||||
# Check common locations
|
|
||||||
for d in /opt/nexus /www/wwwroot/*/; do
|
|
||||||
if [ -d "$d/server" ] && [ -d "$d/web" ]; then
|
|
||||||
DEPLOY_DIR="$d"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# Try from Supervisor config
|
|
||||||
if [ -z "$DEPLOY_DIR" ]; then
|
|
||||||
DEPLOY_DIR=$(supervisorctl status nexus 2>/dev/null | grep -oP 'cwd=\K[^ ,]+' || true)
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$DEPLOY_DIR" ] || [ ! -d "$DEPLOY_DIR/server" ]; then
|
if [[ -z "$DEPLOY_DIR" || ! -d "$DEPLOY_DIR/server" ]]; then
|
||||||
error "Cannot find Nexus installation. Use --deploy-dir to specify."
|
error "找不到 Nexus 安装目录,请使用 --deploy-dir 指定"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
RUNTIME="$(detect_nexus_runtime "$DEPLOY_DIR")"
|
||||||
|
|
||||||
|
if [[ "$RUNTIME" == "docker" ]]; then
|
||||||
|
info "检测到 Docker Compose 运行时,委托 nexus-1panel.sh upgrade"
|
||||||
|
exec env NEXUS_ROOT="$DEPLOY_DIR" bash "$DEPLOY_DIR/deploy/nexus-1panel.sh" upgrade "${EXTRA_ARGS[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
VENV_DIR="$DEPLOY_DIR/venv"
|
VENV_DIR="$DEPLOY_DIR/venv"
|
||||||
ENV_FILE="$DEPLOY_DIR/.env"
|
ENV_FILE="$DEPLOY_DIR/.env"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "=========================================="
|
echo "=========================================="
|
||||||
echo " Nexus 6.0 Upgrade"
|
echo " Nexus 6.0 Upgrade (Supervisor)"
|
||||||
echo "=========================================="
|
echo "=========================================="
|
||||||
echo " Deploy: $DEPLOY_DIR"
|
echo " Deploy: $DEPLOY_DIR"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 1. Pull latest code
|
|
||||||
info "Step 1/4: Updating source code..."
|
info "Step 1/4: Updating source code..."
|
||||||
if [ -d "$DEPLOY_DIR/.git" ]; then
|
if [[ -d "$DEPLOY_DIR/.git" ]]; then
|
||||||
cd "$DEPLOY_DIR"
|
cd "$DEPLOY_DIR"
|
||||||
OLD_REV=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
|
OLD_REV="$(git rev-parse HEAD 2>/dev/null || echo unknown)"
|
||||||
git pull --ff-only 2>/dev/null || {
|
git pull --ff-only 2>/dev/null || {
|
||||||
error "git pull failed. You may have local changes."
|
error "git pull failed. Resolve conflicts: cd $DEPLOY_DIR && git status"
|
||||||
error "Resolve conflicts manually: cd $DEPLOY_DIR && git status"
|
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
NEW_REV=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
|
NEW_REV="$(git rev-parse HEAD 2>/dev/null || echo unknown)"
|
||||||
if [ "$OLD_REV" = "$NEW_REV" ]; then
|
if [[ "$OLD_REV" == "$NEW_REV" ]]; then
|
||||||
info " Already up to date (no new commits)"
|
info " Already up to date (no new commits)"
|
||||||
else
|
else
|
||||||
info " Updated: ${OLD_REV:0:8}..${NEW_REV:0:8}"
|
info " Updated: ${OLD_REV:0:8}..${NEW_REV:0:8}"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
warn " Not a git repo. Skip git pull (update files manually)"
|
warn " Not a git repo. Skip git pull"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 2. Update Python dependencies
|
|
||||||
info "Step 2/4: Updating Python dependencies..."
|
info "Step 2/4: Updating Python dependencies..."
|
||||||
if [ -d "$VENV_DIR/bin" ]; then
|
if [[ -d "$VENV_DIR/bin" ]]; then
|
||||||
"$VENV_DIR/bin/pip" install -q --upgrade pip
|
"$VENV_DIR/bin/pip" install -q --upgrade pip
|
||||||
"$VENV_DIR/bin/pip" install -q -r "$DEPLOY_DIR/requirements.txt" 2>/dev/null || {
|
"$VENV_DIR/bin/pip" install -q -r "$DEPLOY_DIR/requirements.txt" 2>/dev/null || {
|
||||||
warn " pip install had some warnings, but continuing..."
|
warn " pip install had warnings, continuing..."
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error " venv not found at $VENV_DIR. Run install.sh first."
|
error " venv not found at $VENV_DIR. Run install.sh first."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 3. Restart application
|
|
||||||
info "Step 3/4: Restarting Nexus..."
|
info "Step 3/4: Restarting Nexus..."
|
||||||
supervisorctl restart nexus >/dev/null 2>&1 || {
|
supervisorctl restart nexus >/dev/null 2>&1 || {
|
||||||
warn " supervisorctl restart failed. Try manually: supervisorctl restart nexus"
|
warn " supervisorctl restart failed. Try: supervisorctl restart nexus"
|
||||||
}
|
}
|
||||||
|
|
||||||
# 4. Health check
|
|
||||||
info "Step 4/4: Verifying health..."
|
info "Step 4/4: Verifying health..."
|
||||||
|
PORT="$(nexus_publish_port_for "$DEPLOY_DIR")"
|
||||||
# Read port from .env or default
|
|
||||||
PORT=8600
|
|
||||||
if [ -f "$ENV_FILE" ]; then
|
|
||||||
PORT_FROM_ENV=$(grep '^NEXUS_PORT=' "$ENV_FILE" 2>/dev/null | cut -d'=' -f2 || true)
|
|
||||||
[ -n "$PORT_FROM_ENV" ] && PORT="$PORT_FROM_ENV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
HEALTH_OK=false
|
HEALTH_OK=false
|
||||||
for i in $(seq 1 15); do
|
for _ in $(seq 1 15); do
|
||||||
if curl -sf "http://127.0.0.1:$PORT/health" >/dev/null 2>&1; then
|
if curl -sf "http://127.0.0.1:${PORT}/health" >/dev/null 2>&1; then
|
||||||
HEALTH_OK=true
|
HEALTH_OK=true
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
@@ -120,11 +113,12 @@ for i in $(seq 1 15); do
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
if [ "$HEALTH_OK" = true ]; then
|
if [[ "$HEALTH_OK" == true ]]; then
|
||||||
echo -e " ${GREEN}Upgrade complete! Nexus is healthy.${NC}"
|
echo -e " ${GREEN}Upgrade complete! Nexus is healthy.${NC}"
|
||||||
|
suggest_ops_cron "$DEPLOY_DIR"
|
||||||
else
|
else
|
||||||
echo -e " ${YELLOW}Health check pending. Verify manually:${NC}"
|
echo -e " ${YELLOW}Health check pending. Verify manually:${NC}"
|
||||||
echo " curl http://127.0.0.1:$PORT/health"
|
echo " curl http://127.0.0.1:${PORT}/health"
|
||||||
echo " supervisorctl status nexus"
|
echo " supervisorctl status nexus"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# nx 上帝菜单巡检第五轮 — 部署脚本 Docker/Supervisor 分流
|
||||||
|
|
||||||
|
| 项 | 内容 |
|
||||||
|
|----|------|
|
||||||
|
| 日期 | 2026-06-06 |
|
||||||
|
| 动机 | `upgrade.sh`、`deploy-production.sh` 等仍硬编码 Supervisor + `/www/wwwroot`,Docker 1Panel 生产(`/opt/nexus`)无法正确升级 |
|
||||||
|
|
||||||
|
## 变更摘要
|
||||||
|
|
||||||
|
1. **detect_deploy_runtime.sh**(新):共享 `resolve_nexus_root` / `detect_nexus_runtime` / `suggest_ops_cron`。
|
||||||
|
2. **upgrade.sh**:检测到 Docker Compose 栈时 `exec nexus-1panel.sh upgrade`;Supervisor 保留 venv 路径。
|
||||||
|
3. **deploy-production.sh**:SSH 远程探测运行时;Docker 走镜像重建,Supervisor 走 tar 前端 + supervisorctl。
|
||||||
|
4. **deploy-on-server.sh** / **deploy-frontend.sh**:同上自动分流。
|
||||||
|
5. **nexus-1panel.sh upgrade**:成功后若未安装 cron 则提示 `nx cron`。
|
||||||
|
|
||||||
|
## 涉及文件
|
||||||
|
|
||||||
|
- `deploy/detect_deploy_runtime.sh`
|
||||||
|
- `deploy/upgrade.sh`
|
||||||
|
- `deploy/deploy-production.sh`
|
||||||
|
- `deploy/deploy-on-server.sh`
|
||||||
|
- `deploy/deploy-frontend.sh`
|
||||||
|
- `deploy/nexus-1panel.sh`
|
||||||
|
|
||||||
|
## 迁移 / 重启
|
||||||
|
|
||||||
|
- 仅 host 脚本更新,`git pull` 即可;无需 DB 迁移。
|
||||||
|
|
||||||
|
## 验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash -n deploy/detect_deploy_runtime.sh deploy/upgrade.sh deploy/deploy-production.sh
|
||||||
|
# Docker 生产:
|
||||||
|
sudo bash deploy/upgrade.sh --deploy-dir /opt/nexus --check
|
||||||
|
sudo bash deploy/deploy-on-server.sh --help 2>/dev/null || true
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user