50 lines
2.2 KiB
Bash
Executable File
50 lines
2.2 KiB
Bash
Executable File
#!/bin/bash
|
||
# 容器启动脚本:安装依赖 + 环境修复 + 启动 web_server。
|
||
# compose 的 python-app 服务 command 指向本脚本。
|
||
#
|
||
# 为什么需要环境修复(必须在 pip install 之后):
|
||
# rapidocr_onnxruntime 的依赖声明是 opencv-python(GUI 版),pip 解析依赖时
|
||
# 会强制装回它;而 GUI 版依赖 X11 库(libxcb),python:slim 容器里 import cv2
|
||
# 直接崩溃 → RapidOCR 不可用 → 条件判断的 OCR 步骤抛异常 → 任务失败退出。
|
||
# 因此在安装完 requirements 后,最后强制卸载 GUI 版并装 headless(幂等)。
|
||
# 本地 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 版)
|
||
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
|
||
|
||
def cv2_ok():
|
||
try:
|
||
import cv2
|
||
return hasattr(cv2, "__version__") and cv2.__file__ is not None
|
||
except Exception:
|
||
return False
|
||
|
||
if cv2_ok():
|
||
sys.exit(0)
|
||
print("cv2 空壳,wheel 手动解压修复...")
|
||
r = subprocess.run(["pip", "download", "--no-deps", "-q",
|
||
"-i", "https://pypi.tuna.tsinghua.edu.cn/simple",
|
||
"-d", "/tmp/ocv", "opencv-python-headless>=4.8,<5"], capture_output=True)
|
||
if r.returncode != 0:
|
||
sys.exit(1)
|
||
w = sorted(glob.glob("/tmp/ocv/opencv_python_headless*.whl"))[-1]
|
||
with zipfile.ZipFile(w) as z:
|
||
z.extractall("/tmp/ocv")
|
||
dst = os.path.join(site.getsitepackages()[0], "cv2")
|
||
shutil.rmtree(dst, ignore_errors=True)
|
||
shutil.copytree("/tmp/ocv/cv2", dst)
|
||
import cv2
|
||
print(f"cv2 {cv2.__version__} 手动解压修复完成")
|
||
PY
|
||
|
||
exec python -u web_server.py
|