fix: OCR 在一键部署时注册 systemd 开机自启
EOF Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+9
-9
@@ -207,17 +207,17 @@ setup_backend() {
|
||||
}
|
||||
|
||||
setup_ocr_gpu() {
|
||||
if command -v nvidia-smi >/dev/null; then
|
||||
log_info "检测到 NVIDIA GPU,OCR 将常驻显存 (screen)"
|
||||
if command -v nvidia-smi >/dev/null && nvidia-smi >/dev/null 2>&1; then
|
||||
log_info "检测到可用 NVIDIA GPU"
|
||||
nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null || true
|
||||
else
|
||||
log_warn "未检测到 NVIDIA GPU,OCR 将使用 CPU(较慢)"
|
||||
log_warn "未检测到可用 NVIDIA GPU,OCR 将使用 CPU(systemd 开机自启)"
|
||||
fi
|
||||
if [[ -x "${INSTALL_DIR}/deploy/install-ocr-deps.sh" ]]; then
|
||||
bash "${INSTALL_DIR}/deploy/install-ocr-deps.sh" || log_warn "OCR 系统库安装跳过"
|
||||
fi
|
||||
install_ocr_worker
|
||||
start_ocr_screen
|
||||
start_ocr_service
|
||||
wait_ocr_healthy 30 || log_warn "OCR 后台加载中,继续安装主程序…"
|
||||
}
|
||||
|
||||
@@ -286,11 +286,11 @@ print_summary() {
|
||||
echo " 访问: http://${ip}:${WEB_PORT}"
|
||||
echo " 管理员: admin / admin123(请立即修改)"
|
||||
echo ""
|
||||
echo " 【同机 OCR — GPU 常驻 screen】"
|
||||
echo " 【同机 OCR — systemd 开机自启】"
|
||||
echo " OCR 地址: http://127.0.0.1:${OCR_PORT}"
|
||||
echo " 状态: bash ${INSTALL_DIR}/deploy/ocr-screen.sh status"
|
||||
echo " 进入终端: screen -r ocr-worker (Ctrl+A D 退出)"
|
||||
echo " 重启 OCR: bash ${INSTALL_DIR}/deploy/ocr-screen.sh restart"
|
||||
echo " 状态: systemctl status ocr-worker"
|
||||
echo " 重启 OCR: systemctl restart ocr-worker"
|
||||
echo " 日志: journalctl -u ocr-worker -f"
|
||||
echo ""
|
||||
echo " 【Ollama — 其他电脑】"
|
||||
echo " 地址: ${OLLAMA_BASE_URL}"
|
||||
@@ -306,7 +306,7 @@ print_summary() {
|
||||
}
|
||||
|
||||
main() {
|
||||
log_info "一键部署开始(主程序 + OCR/GPU/screen | Ollama 外置)"
|
||||
log_info "一键部署开始(主程序 + OCR/systemd | Ollama 外置)"
|
||||
require_root
|
||||
setup_deploy_proxy
|
||||
check_os
|
||||
|
||||
+72
-38
@@ -1,7 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
# OCR Worker 共用函数:同机 GPU 识别 + screen 常驻
|
||||
# OCR Worker 共用函数:同机 RapidOCR + systemd 开机自启
|
||||
OCR_SCREEN_NAME="${OCR_SCREEN_NAME:-ocr-worker}"
|
||||
OCR_PORT="${OCR_PORT:-23567}"
|
||||
OCR_SERVICE_NAME="${OCR_SERVICE_NAME:-ocr-worker}"
|
||||
|
||||
ocr_worker_dir() {
|
||||
echo "${INSTALL_DIR}/deploy/ocr-worker"
|
||||
@@ -21,8 +22,10 @@ detect_ocr_use_gpu() {
|
||||
fi
|
||||
return
|
||||
fi
|
||||
# auto
|
||||
if command -v nvidia-smi >/dev/null && ldconfig -p 2>/dev/null | grep -q libcudnn; then
|
||||
# auto:有 nvidia-smi 且能看到 GPU 才开(无卡时驱动在也会失败)
|
||||
if command -v nvidia-smi >/dev/null \
|
||||
&& nvidia-smi >/dev/null 2>&1 \
|
||||
&& ldconfig -p 2>/dev/null | grep -q libcudnn; then
|
||||
echo "true"
|
||||
else
|
||||
echo "false"
|
||||
@@ -45,41 +48,64 @@ ocr_screen_running() {
|
||||
screen -list 2>/dev/null | grep -q "\.${OCR_SCREEN_NAME}[[:space:]]"
|
||||
}
|
||||
|
||||
start_ocr_screen() {
|
||||
local worker_dir log_file
|
||||
worker_dir="$(ocr_worker_dir)"
|
||||
if [[ ! -x "${worker_dir}/.venv/bin/uvicorn" ]]; then
|
||||
log_warn "OCR Worker 未安装,跳过 screen 启动"
|
||||
return 1
|
||||
fi
|
||||
if ! command -v screen >/dev/null; then
|
||||
log_error "未安装 screen,请 apt install screen"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "启动 OCR Worker → screen「${OCR_SCREEN_NAME}」(RapidOCR, 端口 ${OCR_PORT})"
|
||||
stop_ocr_screen() {
|
||||
if ocr_screen_running; then
|
||||
log_info "停止旧版 OCR screen 会话…"
|
||||
screen -S "${OCR_SCREEN_NAME}" -X quit 2>/dev/null || true
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
mkdir -p "${INSTALL_DIR}/logs" 2>/dev/null || true
|
||||
log_file="${INSTALL_DIR}/logs/ocr-worker.log"
|
||||
|
||||
screen -dmS "${OCR_SCREEN_NAME}" bash -c "
|
||||
cd '${worker_dir}' &&
|
||||
export OCR_PORT='${OCR_PORT}' OCR_HOST=0.0.0.0 &&
|
||||
exec bash run.sh >> '${log_file}' 2>&1
|
||||
"
|
||||
sleep 2
|
||||
log_info "OCR 日志: ${log_file}"
|
||||
}
|
||||
|
||||
stop_ocr_screen() {
|
||||
if ocr_screen_running; then
|
||||
log_info "停止 OCR screen 会话…"
|
||||
screen -S "${OCR_SCREEN_NAME}" -X quit 2>/dev/null || true
|
||||
# 注册并启用 systemd(一键部署 / 更新时调用)
|
||||
setup_ocr_systemd() {
|
||||
local worker_dir use_gpu
|
||||
worker_dir="$(ocr_worker_dir)"
|
||||
if [[ ! -x "${worker_dir}/.venv/bin/uvicorn" ]]; then
|
||||
log_warn "OCR Worker 未安装,跳过 systemd 注册"
|
||||
return 1
|
||||
fi
|
||||
|
||||
use_gpu="$(detect_ocr_use_gpu)"
|
||||
stop_ocr_screen
|
||||
|
||||
log_info "注册 systemd 服务 ${OCR_SERVICE_NAME}(OCR_USE_GPU=${use_gpu}, 端口 ${OCR_PORT})…"
|
||||
cat > "/etc/systemd/system/${OCR_SERVICE_NAME}.service" <<EOF
|
||||
[Unit]
|
||||
Description=Grade Archive OCR Worker (RapidOCR)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=${worker_dir}
|
||||
Environment=OCR_USE_GPU=${use_gpu}
|
||||
Environment=OCR_PORT=${OCR_PORT}
|
||||
Environment=OCR_HOST=0.0.0.0
|
||||
ExecStart=${worker_dir}/.venv/bin/uvicorn app:app --host 0.0.0.0 --port ${OCR_PORT} --log-level info
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable "${OCR_SERVICE_NAME}"
|
||||
}
|
||||
|
||||
start_ocr_service() {
|
||||
setup_ocr_systemd || return 1
|
||||
log_info "启动 OCR systemd 服务…"
|
||||
systemctl restart "${OCR_SERVICE_NAME}"
|
||||
}
|
||||
|
||||
stop_ocr_service() {
|
||||
systemctl stop "${OCR_SERVICE_NAME}" 2>/dev/null || true
|
||||
stop_ocr_screen
|
||||
}
|
||||
|
||||
# 兼容旧脚本名
|
||||
start_ocr_screen() {
|
||||
start_ocr_service
|
||||
}
|
||||
|
||||
wait_ocr_healthy() {
|
||||
@@ -92,24 +118,32 @@ wait_ocr_healthy() {
|
||||
return 0
|
||||
fi
|
||||
if (( i % 5 == 0 )); then
|
||||
echo -ne "\r${YELLOW}[INFO]${NC} 仍在等待 OCR… ${i}/${max}(可另开终端: tail -f ${INSTALL_DIR}/logs/ocr-worker.log)"
|
||||
echo -ne "\r${YELLOW}[INFO]${NC} 仍在等待 OCR… ${i}/${max}(journalctl -u ${OCR_SERVICE_NAME} -f)"
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
echo ""
|
||||
log_warn "OCR 尚未响应(可能仍在下载/加载模型,主程序可先继续)"
|
||||
log_warn "稍后执行: bash ${INSTALL_DIR}/deploy/ocr-screen.sh status"
|
||||
log_warn "稍后执行: systemctl status ${OCR_SERVICE_NAME}"
|
||||
return 1
|
||||
}
|
||||
|
||||
show_ocr_status() {
|
||||
echo ""
|
||||
echo "--- OCR Worker (screen: ${OCR_SCREEN_NAME}) ---"
|
||||
if ocr_screen_running; then
|
||||
echo "screen: 运行中"
|
||||
screen -list 2>/dev/null | grep "${OCR_SCREEN_NAME}" || true
|
||||
echo "--- OCR Worker (systemd: ${OCR_SERVICE_NAME}) ---"
|
||||
if systemctl is-enabled "${OCR_SERVICE_NAME}" &>/dev/null; then
|
||||
echo "开机自启: $(systemctl is-enabled "${OCR_SERVICE_NAME}" 2>/dev/null)"
|
||||
else
|
||||
echo "screen: 未运行"
|
||||
echo "开机自启: 未注册"
|
||||
fi
|
||||
if systemctl is-active "${OCR_SERVICE_NAME}" &>/dev/null; then
|
||||
echo "服务状态: active"
|
||||
else
|
||||
echo "服务状态: $(systemctl is-active "${OCR_SERVICE_NAME}" 2>/dev/null || echo inactive)"
|
||||
fi
|
||||
if ocr_screen_running; then
|
||||
echo "screen(旧): 仍在运行(建议交由 systemd 接管)"
|
||||
screen -list 2>/dev/null | grep "${OCR_SCREEN_NAME}" || true
|
||||
fi
|
||||
if curl -sf "http://127.0.0.1:${OCR_PORT}/health" 2>/dev/null; then
|
||||
echo ""
|
||||
|
||||
+34
-21
@@ -1,53 +1,66 @@
|
||||
#!/usr/bin/env bash
|
||||
# OCR Worker screen 管理(主程序同机部署时使用)
|
||||
# OCR Worker 管理(systemd 开机自启;兼容旧 screen 命令)
|
||||
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"
|
||||
# shellcheck source=ocr-common.sh
|
||||
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/ocr-common.sh"
|
||||
|
||||
# 最小日志(单独运行时)
|
||||
if ! declare -F log_info >/dev/null 2>&1; then
|
||||
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; }
|
||||
fi
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
用法: bash deploy/ocr-screen.sh <命令>
|
||||
|
||||
start 启动 OCR Worker(screen 后台,GPU 常驻)
|
||||
stop 停止 screen 会话
|
||||
restart 重启
|
||||
status 查看 screen / health / GPU
|
||||
attach 进入 screen 终端(Ctrl+A D 退出)
|
||||
|
||||
start 启动 OCR(systemd,开机自启)
|
||||
stop 停止 OCR
|
||||
restart 重启 OCR
|
||||
status 查看服务 / health
|
||||
enable 仅注册开机自启(不重启)
|
||||
logs 跟踪日志
|
||||
EOF
|
||||
}
|
||||
|
||||
cmd="${1:-status}"
|
||||
|
||||
case "${cmd}" in
|
||||
start)
|
||||
start_ocr_screen
|
||||
start_ocr_service
|
||||
wait_ocr_healthy || true
|
||||
show_ocr_status
|
||||
;;
|
||||
stop)
|
||||
stop_ocr_screen
|
||||
stop_ocr_service
|
||||
log_info "OCR 已停止"
|
||||
;;
|
||||
restart)
|
||||
stop_ocr_screen
|
||||
sleep 1
|
||||
start_ocr_screen
|
||||
stop_ocr_service
|
||||
start_ocr_service
|
||||
wait_ocr_healthy || true
|
||||
show_ocr_status
|
||||
;;
|
||||
status)
|
||||
show_ocr_status
|
||||
;;
|
||||
enable)
|
||||
setup_ocr_systemd
|
||||
log_info "已 enable,启动请: bash deploy/ocr-screen.sh start"
|
||||
;;
|
||||
logs)
|
||||
journalctl -u "${OCR_SERVICE_NAME}" -f
|
||||
;;
|
||||
attach)
|
||||
if ocr_screen_running; then
|
||||
screen -r "${OCR_SCREEN_NAME}"
|
||||
else
|
||||
log_error "screen 未运行,请先: bash deploy/ocr-screen.sh start"
|
||||
exit 1
|
||||
fi
|
||||
log_warn "OCR 已改为 systemd,不再使用 screen attach"
|
||||
log_info "查看日志: journalctl -u ${OCR_SERVICE_NAME} -f"
|
||||
;;
|
||||
-h|--help|help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
# 注册 OCR Worker 为 systemd 服务(后台常驻)
|
||||
# 注册 OCR Worker 为 systemd 服务(后台常驻 + 开机自启)
|
||||
# 推荐:由 deploy/install.sh / update.sh 自动调用;也可单独执行。
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")" && pwd)"
|
||||
INSTALL_DIR="${INSTALL_DIR:-$(cd "${ROOT}/../.." && pwd)}"
|
||||
PORT="${OCR_PORT:-23567}"
|
||||
|
||||
# shellcheck source=../ocr-common.sh
|
||||
source "$(cd "$(dirname "$0")/.." && pwd)/ocr-common.sh"
|
||||
|
||||
# 提供最小 log_*,以便单独运行
|
||||
if ! declare -F log_info >/dev/null 2>&1; then
|
||||
log_info() { echo "[INFO] $*"; }
|
||||
log_warn() { echo "[WARN] $*"; }
|
||||
log_error() { echo "[ERROR] $*" >&2; }
|
||||
fi
|
||||
|
||||
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
|
||||
echo "请使用 root 运行: sudo bash install-service.sh"
|
||||
exit 1
|
||||
@@ -15,39 +27,18 @@ if [[ ! -d "${ROOT}/.venv" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod +x "${ROOT}/start.sh" "${ROOT}/check.sh" "${ROOT}/install.sh"
|
||||
chmod +x "${ROOT}/start.sh" "${ROOT}/check.sh" "${ROOT}/install.sh" 2>/dev/null || true
|
||||
|
||||
cat > /etc/systemd/system/ocr-worker.service <<EOF
|
||||
[Unit]
|
||||
Description=Grade Archive OCR Worker (PaddleOCR)
|
||||
After=network.target
|
||||
start_ocr_service
|
||||
wait_ocr_healthy 20 || true
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=${ROOT}
|
||||
Environment=OCR_USE_GPU=true
|
||||
Environment=OCR_PORT=${PORT}
|
||||
Environment=OCR_HOST=0.0.0.0
|
||||
ExecStart=${ROOT}/.venv/bin/uvicorn app:app --host 0.0.0.0 --port ${PORT} --log-level info
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable ocr-worker
|
||||
systemctl restart ocr-worker
|
||||
|
||||
sleep 2
|
||||
echo ""
|
||||
echo "==> 服务状态:"
|
||||
systemctl status ocr-worker --no-pager -l | head -20
|
||||
|
||||
echo ""
|
||||
echo "==> 健康检查:"
|
||||
curl -sS "http://127.0.0.1:${PORT}/health" || echo "(尚未就绪,请稍等 30 秒后重试: bash check.sh)"
|
||||
curl -sS "http://127.0.0.1:${PORT}/health" || echo "(尚未就绪,请稍等后: curl http://127.0.0.1:${PORT}/health)"
|
||||
echo ""
|
||||
echo "局域网地址: http://$(hostname -I 2>/dev/null | awk '{print $1}'):${PORT}"
|
||||
echo "成绩档案系统设置 OCR 地址填: http://192.168.8.6:${PORT} (按实际 IP 修改)"
|
||||
echo "管理: systemctl status|restart|stop ocr-worker"
|
||||
echo "日志: journalctl -u ocr-worker -f"
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ log_info "开始修复 grade-archive 服务…"
|
||||
stop_legacy_pm2
|
||||
install_ocr_deps_safe
|
||||
if [[ -x "${INSTALL_DIR}/deploy/ocr-worker/.venv/bin/uvicorn" ]]; then
|
||||
start_ocr_screen || log_warn "OCR screen 启动失败"
|
||||
start_ocr_service || log_warn "OCR systemd 启动失败"
|
||||
wait_ocr_healthy || log_warn "OCR 未就绪"
|
||||
fi
|
||||
setup_systemd_service
|
||||
|
||||
+3
-4
@@ -39,11 +39,10 @@ pip_install_with_fallback -r requirements.txt
|
||||
deactivate
|
||||
cd "${INSTALL_DIR}"
|
||||
|
||||
log_info "更新 OCR Worker 并重启 screen…"
|
||||
log_info "更新 OCR Worker 并重启 systemd 服务…"
|
||||
install_ocr_worker
|
||||
stop_ocr_screen
|
||||
start_ocr_screen
|
||||
wait_ocr_healthy || log_warn "OCR 加载中,稍后: bash deploy/ocr-screen.sh status"
|
||||
start_ocr_service
|
||||
wait_ocr_healthy || log_warn "OCR 加载中,稍后: systemctl status ocr-worker"
|
||||
|
||||
stop_legacy_pm2
|
||||
install_ocr_deps_safe
|
||||
|
||||
@@ -196,8 +196,12 @@ systemctl status grade-archive # 查看状态
|
||||
```bash
|
||||
sudo systemctl stop ocr-worker
|
||||
sudo systemctl start ocr-worker
|
||||
sudo systemctl status ocr-worker
|
||||
journalctl -u ocr-worker -f
|
||||
```
|
||||
|
||||
一键部署会自动 `systemctl enable ocr-worker`,重启后 OCR 随系统启动。
|
||||
|
||||
停止后浏览器访问 `http://<服务器IP>:23566` 会无法连接;启动后即可恢复。
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user