fix: 容器启动幂等——依赖安装段移入 start.sh 并加「就绪即跳过」守卫(flask/u2/rapidocr/cv2 全部可用则秒级启动);配合 220 compose 去掉 command 里的 pip 段,消除每次容器重启重装 opencv 5.0(73MB) 并破坏 cv2 的崩溃循环帮凶

This commit is contained in:
2026-09-04 16:23:17 +08:00
parent fbd01a056c
commit 7fd77fa33c
+33 -11
View File
@@ -1,6 +1,7 @@
#!/bin/bash #!/bin/bash
# 容器启动脚本:安装依赖 + 环境修复 + 启动 web_server。 # 容器启动脚本:依赖安装(仅首次/缺失时)+ 环境修复 + 启动 web_server。
# compose 的 python-app 服务 command 指向本脚本。 # compose 的 python-app 服务 command 指向本脚本(不要在 compose 里再跑 pip,
# 否则每次容器重启都重装依赖——实测每轮重新下载 opencv 5.0(73MB) 并破坏 cv2)。
# #
# 为什么需要环境修复(必须在 pip install 之后): # 为什么需要环境修复(必须在 pip install 之后):
# rapidocr_onnxruntime 的依赖声明是 opencv-python(GUI 版),pip 解析依赖时 # rapidocr_onnxruntime 的依赖声明是 opencv-python(GUI 版),pip 解析依赖时
@@ -8,17 +9,35 @@
# 直接崩溃 → RapidOCR 不可用 → 条件判断的 OCR 步骤抛异常 → 任务失败退出。 # 直接崩溃 → RapidOCR 不可用 → 条件判断的 OCR 步骤抛异常 → 任务失败退出。
# 因此在安装完 requirements 后,最后强制卸载 GUI 版并装 headless(幂等)。 # 因此在安装完 requirements 后,最后强制卸载 GUI 版并装 headless(幂等)。
# 本地 Mac 有 GUI 环境不受影响。 # 本地 Mac 有 GUI 环境不受影响。
if [ -f requirements.txt ]; then
pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
fi
# 环境修复:最后强制 headless(覆盖 rapidocr 拉回的 GUI 版) # ---- 依赖就绪守卫:flask/u2/uiautodev/rapidocr/cv2 全部可用则跳过安装 ----
pip uninstall -y -q opencv-python 2>/dev/null || true # (容器重启秒级启动;只有首次部署或依赖缺失时才走完整安装)
pip install -q -i https://pypi.tuna.tsinghua.edu.cn/simple "opencv-python-headless>=4.8,<5" # 5.x wheel 无 cv2 模块,锁定 4.x
# pip 24.0 解压 abi3 wheel 偶发丢根文件(4.14.0.94 实测 site-packages/cv2 只剩子目录,
# cv2.abi3.so / __init__.py 缺失 → import cv2 成空壳,OCR 全挂)→ 空壳检测 + wheel 手动解压兜底(幂等)
python3 - <<'PY' python3 - <<'PY'
import importlib.util, sys
mods = ("flask", "flask_login", "flask_sqlalchemy", "apscheduler",
"uiautomator2", "uiautodev", "rapidocr_onnxruntime", "PIL")
if all(importlib.util.find_spec(m) for m in mods):
try:
import cv2
ok = hasattr(cv2, "__version__") and cv2.__file__ is not None
except Exception:
ok = False
sys.exit(0 if ok else 1)
sys.exit(1)
PY
if [ $? -ne 0 ]; then
echo "[start] 依赖缺失或 cv2 异常,执行安装与环境修复(首次启动较慢)..."
if [ -f requirements.txt ]; then
pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
fi
# 环境修复:最后强制 headless(覆盖 rapidocr 拉回的 GUI 版)
pip uninstall -y -q opencv-python 2>/dev/null || true
pip install -q -i https://pypi.tuna.tsinghua.edu.cn/simple "opencv-python-headless>=4.8,<5" # 5.x wheel 无 cv2 模块,锁定 4.x
# pip 24.0 解压 abi3 wheel 偶发丢根文件(4.14.0.94 实测 site-packages/cv2 只剩子目录,
# cv2.abi3.so / __init__.py 缺失 → import cv2 成空壳,OCR 全挂)→ 空壳检测 + wheel 手动解压兜底(幂等)
python3 - <<'PY'
import glob, os, shutil, site, subprocess, sys, zipfile import glob, os, shutil, site, subprocess, sys, zipfile
def cv2_ok(): def cv2_ok():
@@ -45,6 +64,9 @@ shutil.copytree("/tmp/ocv/cv2", dst)
import cv2 import cv2
print(f"cv2 {cv2.__version__} 手动解压修复完成") print(f"cv2 {cv2.__version__} 手动解压修复完成")
PY PY
else
echo "[start] 依赖已就绪(cv2 $(python3 -c 'import cv2; print(cv2.__version__)' 2>/dev/null)),跳过安装"
fi
# 启动 MCP server(后台,AI 控制台/外部客户端经 127.0.0.1:8033 调用)。 # 启动 MCP server(后台,AI 控制台/外部客户端经 127.0.0.1:8033 调用)。
# web_server.py 内 agent 依赖它,容器重启必须自动拉起(MCP_ENABLED=0 可关)。 # web_server.py 内 agent 依赖它,容器重启必须自动拉起(MCP_ENABLED=0 可关)。