# 极限低配版:1 核 CPU / 2G 内存。镜像层尽量小,运行期只跑 1 个 worker。 # 注意:不要加 "# syntax=docker/dockerfile:1" —— 那是 BuildKit 前端镜像指令, # 构建时会去拉 docker/dockerfile:1,国内 NAS 的镜像加速源常不代理这个冷门镜像。 # # 基础镜像:直接写国内镜像仓库全路径,绕过 daemon 的 registry-mirrors 配置。 # 原因:fnOS 的 Docker 应用会用自己的界面配置覆盖 /etc/docker/daemon.json, # 加速源一旦失效(如 docker.fnnas.com 未授权返回 401)手工改配置不生效。 # 海外环境或自建源可覆盖:--build-arg BASE_IMAGE=python:3.11-slim # 备用源:docker.1ms.run/library/python:3.11-slim # mirror.ccs.tencentyun.com/library/python:3.11-slim ARG BASE_IMAGE=docker.m.daocloud.io/library/python:3.11-slim FROM ${BASE_IMAGE} ENV PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ HOME=/app \ OMP_NUM_THREADS=1 \ OPENBLAS_NUM_THREADS=1 \ MKL_NUM_THREADS=1 \ OMP_DISPLAY_AFFINITY=FALSE \ OMP_PROC_BIND=FALSE \ MAX_IMAGE_BYTES=5242880 \ MAX_SIDE=1200 \ MAX_DIMENSION=6000 \ DET_LIMIT_SIDE_LEN=960 \ REC_BATCH_NUM=1 \ RAPIDOCR_MODEL_DIR=/app/models WORKDIR /app # 只装运行必需的系统库,装完立刻清缓存,压镜像体积 RUN apt-get update && apt-get install -y --no-install-recommends \ libgomp1 libgl1 libglib2.0-0 \ && rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* COPY requirements.txt . # pip 默认走清华源(国内 NAS 直连 pypi.org 慢且常断)。注意这与镜像加速源无关, # 是独立的网络路径。需要时构建可覆盖:--build-arg PIP_INDEX_URL=https://pypi.org/simple ARG PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple # opencv-python 带 GUI 依赖(多 60MB+ 系统库),rapidocr 只用到 imread/imwrite, # 换 headless 版对运行内存无影响,纯粹是给镜像瘦身 RUN pip install --no-cache-dir -i $PIP_INDEX_URL -r requirements.txt \ && pip uninstall -y opencv-python opencv-contrib-python >/dev/null 2>&1 || true \ && pip install --no-cache-dir -i $PIP_INDEX_URL opencv-python-headless # 构建期预热:把 onnx 模型下进镜像 /app/models,运行时不再依赖外网。 # 注意:如果 rapidocr_onnxruntime 忽略 model_dir 参数,模型会落到 $HOME/.rapidocr_model, # 所以上面把 HOME 也指到 /app,两种路径都在 /app 下,卷挂载能一并覆盖。 COPY app ./app RUN python -c "from rapidocr_onnxruntime import RapidOCR; RapidOCR()" \ && python -c "import app.main as m; m.get_engine()" EXPOSE 8000 # 单 worker:每个 worker 都会独立加载一份模型,低配下不要加 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"]