105 lines
4.9 KiB
Docker
105 lines
4.9 KiB
Docker
# syntax=m.daocloud.io/docker.io/docker/dockerfile:1.7
|
||
# ---------------------------------------------------------------------------
|
||
# 禁止「FROM python:...」简写 — 会直连 docker.io / registry-1.docker.io。
|
||
# Python 使用 DaoCloud 增加前缀形式:https://github.com/DaoCloud/public-image-mirror
|
||
# 勿用裸 tag「3.13」;须 3.13-slim-bookworm。
|
||
# ---------------------------------------------------------------------------
|
||
FROM m.daocloud.io/docker.io/library/python:3.13-slim-bookworm
|
||
|
||
# Debian bookworm: use Aliyun mirror for apt (default snapshot points at deb.debian.org).
|
||
RUN sed -i \
|
||
-e 's|http://deb.debian.org/debian-security|https://mirrors.aliyun.com/debian-security|g' \
|
||
-e 's|http://deb.debian.org/debian|https://mirrors.aliyun.com/debian|g' \
|
||
/etc/apt/sources.list.d/debian.sources
|
||
|
||
# OpenCV / MediaPipe (doctor pose) need GLVND + Mesa GLES/EGL in slim images; omit X11/GUI stack.
|
||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||
ca-certificates \
|
||
curl \
|
||
docker.io \
|
||
ffmpeg \
|
||
fontconfig \
|
||
fonts-noto-cjk \
|
||
fonts-wqy-microhei \
|
||
libegl-mesa0 \
|
||
libegl1 \
|
||
libgbm1 \
|
||
libgl1 \
|
||
libgl1-mesa-dri \
|
||
libglx-mesa0 \
|
||
libgles2 \
|
||
libglib2.0-0 \
|
||
libgomp1 \
|
||
libxcb1 \
|
||
&& fc-cache -fv \
|
||
&& ldconfig \
|
||
&& ldconfig -p | grep -F 'libGLESv2.so.2' >/dev/null \
|
||
&& rm -rf /var/lib/apt/lists/*
|
||
|
||
# ghcr.io:「增加前缀」形式(与 kindest/node 示例一致)
|
||
COPY --from=m.daocloud.io/ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
||
|
||
WORKDIR /app
|
||
|
||
ENV PYTHONUNBUFFERED=1 \
|
||
UV_HTTP_TIMEOUT=600 \
|
||
UV_LINK_MODE=copy \
|
||
TORCH_HOME=/app/.cache/torch \
|
||
YOLO_CONFIG_DIR=/app/.cache/ultralytics
|
||
|
||
COPY pyproject.toml uv.lock main.py alembic.ini ./
|
||
COPY scripts ./scripts/
|
||
COPY app ./app/
|
||
COPY alembic ./alembic/
|
||
# 离线批处理 / demo 直调 algorithm_subprocesses/5.15/main.py(含 weights/)
|
||
COPY algorithm_subprocesses ./algorithm_subprocesses/
|
||
# Bake runtime patches/assets so non-root api never writes the read-only bundle tree.
|
||
COPY app/algorithm_runner/actionformer_release/libs/utils/nms.py \
|
||
algorithm_subprocesses/5.15/code/actionformer_release/libs/utils/nms.py
|
||
RUN mkdir -p algorithm_subprocesses/5.15/doctor_identity_package/.mediapipe_models && \
|
||
curl -fsSL --retry 3 \
|
||
-o algorithm_subprocesses/5.15/doctor_identity_package/.mediapipe_models/pose_landmarker_lite.task \
|
||
"https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task" && \
|
||
test -s algorithm_subprocesses/5.15/doctor_identity_package/.mediapipe_models/pose_landmarker_lite.task
|
||
|
||
# uv.lock pins uv.agentsmirror.com artifact URLs. Rewrite to mainland mirrors (same /packages/... paths).
|
||
# PyPI: Tsinghua | PyTorch wheel index: 南大 (syncs download.pytorch.org / download-r2)
|
||
RUN sed -i \
|
||
-e 's|https://uv.agentsmirror.com/pypi/files/files.pythonhosted.org|https://pypi.tuna.tsinghua.edu.cn|g' \
|
||
-e 's|https://uv.agentsmirror.com/pypi/simple|https://pypi.tuna.tsinghua.edu.cn/simple|g' \
|
||
-e 's|https://download-r2.pytorch.org|https://mirrors.nju.edu.cn/pytorch|g' \
|
||
-e 's|https://download.pytorch.org|https://mirrors.nju.edu.cn/pytorch|g' \
|
||
uv.lock
|
||
|
||
ENV UV_DEFAULT_INDEX=https://pypi.tuna.tsinghua.edu.cn/simple
|
||
|
||
# VideoSwin (Swin3D-T) hub weights: bake at build time so RTSP batch jobs never hit pytorch.org at runtime.
|
||
# Domestic PyPI mirrors (NJU/Tsinghua/Aliyun) only sync pip wheels, not /models/*.pth; default tries
|
||
# uv.agentsmirror.com (same ecosystem as uv.lock) then download.pytorch.org. Optional offline bake:
|
||
# backend/weights/swin3d_t-7615ae03.pth (see weights/.gitkeep)
|
||
# Override: --build-arg PYTORCH_MODELS_URL=... or PYTORCH_MODELS_MIRROR=...
|
||
ARG PYTORCH_MODELS_MIRROR=
|
||
ARG PYTORCH_MODELS_URL=
|
||
ENV PYTORCH_MODELS_MIRROR=${PYTORCH_MODELS_MIRROR} \
|
||
PYTORCH_MODELS_URL=${PYTORCH_MODELS_URL}
|
||
# Optional offline weight (only .gitkeep by default; add swin3d_t-7615ae03.pth before build if needed).
|
||
COPY weights ./weights/
|
||
|
||
RUN --mount=type=cache,target=/root/.cache/uv \
|
||
uv sync --frozen --no-dev --no-compile --refresh-package numpy --refresh-package mediapipe && \
|
||
.venv/bin/python -c "import alembic" && \
|
||
.venv/bin/python -c "import numpy; import numpy.lib._index_tricks_impl" && \
|
||
.venv/bin/python -c "import mediapipe as mp; print('mediapipe', mp.__version__)" && \
|
||
mkdir -p /app/.cache/ultralytics && \
|
||
PYTORCH_MODELS_LOCAL_PATH=/app/weights/swin3d_t-7615ae03.pth \
|
||
.venv/bin/python scripts/bake_torch_hub_checkpoint.py && \
|
||
rm -rf /app/weights && \
|
||
TORCH_HOME=/app/.cache/torch .venv/bin/python -c "from torchvision.models.video import Swin3D_T_Weights, swin3d_t; swin3d_t(weights=Swin3D_T_Weights.KINETICS400_V1); print('swin3d_t cached ok')" && \
|
||
chmod -R a+rX /app/.venv /app/algorithm_subprocesses /app/.cache/torch /app/.cache/ultralytics
|
||
|
||
ENV PATH="/app/.venv/bin:$PATH"
|
||
|
||
EXPOSE 8000
|
||
|
||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|