fix: OCR 在一键部署时注册 systemd 开机自启

EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-18 00:31:13 +08:00
parent 8cf375d178
commit 2fea777600
7 changed files with 142 additions and 101 deletions
+72 -38
View File
@@ -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 ""