From c42cd0b46d1f6e084e5917426272c0ff9fbc50e2 Mon Sep 17 00:00:00 2001 From: dekun Date: Sun, 28 Jun 2026 14:03:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9B=B4=E6=96=B0=E5=90=8E?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E6=97=A0=E6=B3=95=E8=AE=BF=E9=97=AE=EF=BC=9A?= =?UTF-8?q?=E5=BC=BA=E5=88=B6=20systemd=20=E9=85=8D=E7=BD=AE=E4=B8=8E?= =?UTF-8?q?=E5=81=A5=E5=BA=B7=E6=A3=80=E6=9F=A5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - update.sh 必须 root 运行,自动注册并重启 grade-archive - 新增 deploy/repair.sh 一键修复连接被拒绝 --- deploy/common.sh | 80 ++++++++++++++++++++++++++++++++++++ deploy/grade-archive.service | 1 + deploy/repair.sh | 35 ++++++++++++++++ deploy/update.sh | 34 +++++++-------- docs/DEPLOY.md | 26 +++++++++++- 5 files changed, 156 insertions(+), 20 deletions(-) create mode 100644 deploy/common.sh create mode 100644 deploy/repair.sh diff --git a/deploy/common.sh b/deploy/common.sh new file mode 100644 index 0000000..aef83f1 --- /dev/null +++ b/deploy/common.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# 部署脚本共用函数 +INSTALL_DIR="${INSTALL_DIR:-/opt/secondary-school-grade-archive}" +WEB_PORT="${WEB_PORT:-23566}" + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +log_info() { echo -e "${GREEN}[INFO]${NC} $*"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } + +require_root() { + if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then + log_error "请使用 root 运行: sudo bash $*" + exit 1 + fi +} + +load_env_port() { + if [[ -f "${INSTALL_DIR}/.env" ]]; then + # shellcheck disable=SC1090 + set -a && source "${INSTALL_DIR}/.env" && set +a + fi + WEB_PORT="${WEB_PORT:-23566}" +} + +stop_legacy_pm2() { + if command -v pm2 &>/dev/null; then + pm2 delete grade-api grade-web 2>/dev/null || true + pm2 save 2>/dev/null || true + log_info "已停止旧版 PM2 进程" + fi +} + +setup_systemd_service() { + log_info "配置 systemd 服务 grade-archive…" + sed "s|/opt/secondary-school-grade-archive|${INSTALL_DIR}|g" \ + "${INSTALL_DIR}/deploy/grade-archive.service" > /etc/systemd/system/grade-archive.service + systemctl daemon-reload + systemctl enable grade-archive +} + +restart_grade_service() { + load_env_port + mkdir -p "${INSTALL_DIR}/uploads" "${INSTALL_DIR}/backups" + chmod +x "${INSTALL_DIR}/deploy/start.sh" + log_info "重启 grade-archive(端口 ${WEB_PORT})…" + systemctl restart grade-archive +} + +wait_healthy() { + load_env_port + local i + for i in $(seq 1 30); do + if curl -sf "http://127.0.0.1:${WEB_PORT}/api/health" >/dev/null 2>&1; then + log_info "健康检查通过 — http://127.0.0.1:${WEB_PORT}" + return 0 + fi + sleep 2 + done + log_error "服务未响应,请查看日志:" + journalctl -u grade-archive -n 40 --no-pager || true + return 1 +} + +install_ocr_deps_safe() { + if [[ -x "${INSTALL_DIR}/deploy/install-ocr-deps.sh" ]]; then + bash "${INSTALL_DIR}/deploy/install-ocr-deps.sh" || log_warn "OCR 依赖安装跳过(可稍后重试)" + fi +} + +show_service_status() { + echo "" + systemctl status grade-archive --no-pager -l 2>/dev/null || true + echo "" + ss -tlnp 2>/dev/null | grep -E ":${WEB_PORT}\s" || echo "端口 ${WEB_PORT} 未监听" +} diff --git a/deploy/grade-archive.service b/deploy/grade-archive.service index fdac791..36f3db6 100644 --- a/deploy/grade-archive.service +++ b/deploy/grade-archive.service @@ -9,6 +9,7 @@ WorkingDirectory=/opt/secondary-school-grade-archive ExecStart=/opt/secondary-school-grade-archive/deploy/start.sh Restart=always RestartSec=5 +TimeoutStartSec=120 EnvironmentFile=-/opt/secondary-school-grade-archive/.env [Install] diff --git a/deploy/repair.sh b/deploy/repair.sh new file mode 100644 index 0000000..41c3dc2 --- /dev/null +++ b/deploy/repair.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# +# 服务无法访问(连接被拒绝)时一键修复 +# 用法: sudo bash deploy/repair.sh +# +set -euo pipefail + +INSTALL_DIR="${INSTALL_DIR:-/opt/secondary-school-grade-archive}" + +# shellcheck source=common.sh +source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" + +require_root "deploy/repair.sh" + +cd "${INSTALL_DIR}" || exit 1 +find "${INSTALL_DIR}" -name "*.sh" -exec sed -i 's/\r$//' {} + + +log_info "开始修复 grade-archive 服务…" + +stop_legacy_pm2 +install_ocr_deps_safe +setup_systemd_service +restart_grade_service + +if wait_healthy; then + ip=$(hostname -I 2>/dev/null | awk '{print $1}') + ip="${ip:-127.0.0.1}" + echo "" + echo "==========================================" + echo " 修复完成,请访问: http://${ip}:${WEB_PORT}" + echo "==========================================" +else + show_service_status + exit 1 +fi diff --git a/deploy/update.sh b/deploy/update.sh index 43ccb0a..e67b27b 100644 --- a/deploy/update.sh +++ b/deploy/update.sh @@ -5,18 +5,16 @@ INSTALL_DIR="${INSTALL_DIR:-/opt/secondary-school-grade-archive}" BRANCH="${BRANCH:-main}" PIP_MIRROR="${PIP_MIRROR:-https://pypi.tuna.tsinghua.edu.cn/simple}" -GREEN='\033[0;32m' -RED='\033[0;31m' -NC='\033[0m' -log_info() { echo -e "${GREEN}[INFO]${NC} $*"; } -log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } - +# shellcheck source=common.sh +source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" # shellcheck source=proxy.sh source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/proxy.sh" +require_root "deploy/update.sh" + cd "${INSTALL_DIR}" || exit 1 find "${INSTALL_DIR}" -name "*.sh" -exec sed -i 's/\r$//' {} + -chmod +x deploy/start.sh +chmod +x deploy/start.sh deploy/install-ocr-deps.sh deploy/repair.sh setup_deploy_proxy @@ -27,7 +25,6 @@ git pull origin "${BRANCH}" if [[ ! -f "${INSTALL_DIR}/frontend/dist/index.html" ]]; then log_error "未找到 frontend/dist/index.html" - log_error "请先在开发机构建前端并推送到仓库: cd frontend && npm run build && git add frontend/dist && git push" exit 1 fi @@ -36,17 +33,16 @@ cd backend source venv/bin/activate pip install -r requirements.txt --progress-bar on -i "${PIP_MIRROR}" deactivate +cd "${INSTALL_DIR}" -if command -v pm2 &>/dev/null; then - pm2 delete grade-api grade-web 2>/dev/null || true +stop_legacy_pm2 +install_ocr_deps_safe +setup_systemd_service +restart_grade_service + +if ! wait_healthy; then + log_error "更新后服务异常,可尝试: sudo bash ${INSTALL_DIR}/deploy/repair.sh" + exit 1 fi -if [[ "${EUID:-$(id -u)}" -eq 0 ]]; then - log_info "检查 OCR 系统依赖(libGL)…" - bash "${INSTALL_DIR}/deploy/install-ocr-deps.sh" -fi - -log_info "重启 systemd 服务…" -systemctl restart grade-archive - -log_info "更新完成 — 访问端口见 .env 中 WEB_PORT(默认 23566)" +log_info "更新完成" diff --git a/docs/DEPLOY.md b/docs/DEPLOY.md index cab0e64..e320702 100644 --- a/docs/DEPLOY.md +++ b/docs/DEPLOY.md @@ -236,6 +236,30 @@ sudo bash deploy/update.sh --- -## 10. 技术支持 +## 10. 更新后无法访问(连接被拒绝) + +若浏览器提示 **ERR_CONNECTION_REFUSED**,通常是 `update.sh` 停止了旧 PM2,但 **systemd 服务未成功启动**。 + +在服务器执行一键修复: + +```bash +cd /opt/secondary-school-grade-archive +git pull +sudo bash deploy/repair.sh +``` + +手动排查: + +```bash +systemctl status grade-archive +journalctl -u grade-archive -n 50 --no-pager +ss -tlnp | grep 23566 +``` + +> **注意:** `update.sh` / `repair.sh` 必须用 **root** 运行(`sudo bash ...`)。 + +--- + +## 11. 技术支持 微信 **dekun03** · 手机 **18364911125**