diff --git a/workers/extract-worker/.dockerignore b/workers/extract-worker/.dockerignore index f1c3a14..e1222e7 100644 --- a/workers/extract-worker/.dockerignore +++ b/workers/extract-worker/.dockerignore @@ -5,4 +5,4 @@ !README.md !uv.dist.lock !uv.lock -!io-worker-deps-exclusion.txt \ No newline at end of file +!io-worker-deps-exclusion.txt diff --git a/workers/extract-worker/Dockerfile b/workers/extract-worker/Dockerfile index 5d2ec6a..39d3f50 100644 --- a/workers/extract-worker/Dockerfile +++ b/workers/extract-worker/Dockerfile @@ -1,32 +1,15 @@ -FROM python:3.14-slim-trixie AS extract-worker-builder +# Slim runtime base: debian + uv + the uv-managed interpreter, but not build toolchain. +# The venv built in the *-build stages references the managed interpreter using absolute +# path (see .venv/bin/python -> /root/.local/share/uv/python/...), so we copy it here at +# the same location. Workers are build by copying their /app (venv + code) on top. +FROM debian:trixie-slim AS runtime-base ENV PYTHONUNBUFFERED=1 -ENV UV_HTTP_TIMEOUT=300 -ENV UV_LINK_MODE=copy ENV UV_COMPILE_BYTECODE=1 -ENV UV_NO_DEV=1 - -COPY --from=ghcr.io/astral-sh/uv:0.11.24 /uv /uvx /bin/ - -WORKDIR /app - -FROM debian:trixie-slim AS extract-worker-builder-free-threaded - -ENV PYTHONUNBUFFERED=1 -ENV UV_HTTP_TIMEOUT=300 ENV UV_LINK_MODE=copy -ENV UV_COMPILE_BYTECODE=1 ENV UV_NO_DEV=1 -ENV PYTHON_GIL=0 - -RUN apt update -RUN apt install -y git-all \ - libprotobuf-dev \ - protobuf-compiler \ - zlib1g-dev COPY --from=ghcr.io/astral-sh/uv:0.11.24 /uv /uvx /bin/ -RUN uv python install 3.14t WORKDIR /app @@ -37,10 +20,10 @@ FROM nvidia/cuda:12.9.0-devel-ubuntu24.04 AS flash-attn-builder COPY --from=ghcr.io/astral-sh/uv:0.11.6 /uv /bin/ -RUN uv python install 3.14t +RUN uv python install 3.14 # Install torch from the lockfile by install extras and skipping some packages -RUN --mount=type=cache,target=~/.cache/uv \ +RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.dist.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ uv sync --frozen --no-install-project --no-editable --extra base --extra gpu \ @@ -53,16 +36,16 @@ RUN --mount=type=bind,source=uv.dist.lock,target=uv.lock \ uv export --frozen --extra base-gpu --no-dev | \ sed -n 's/^flash-attn==\([^; ]*\).*/\1/p' > flash-attn-version.txt -RUN --mount=type=cache,target=~/.cache/uv \ +RUN --mount=type=cache,target=/root/.cache/uv \ uv pip install pip && \ MAX_JOBS=8 uv run python -m pip wheel "flash-attn==$(cat flash-attn-version.txt)" \ --no-build-isolation --no-deps -w /flash-attn-wheel -FROM extract-worker-builder AS io-worker +FROM runtime-base AS io-worker ADD io-worker-deps-exclusion.txt ./ # Install deps first to optimize layer cache -RUN --mount=type=cache,target=~/.cache/uv \ +RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.dist.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ uv sync -v --frozen --no-editable --no-install-project $(sed 's/^/--no-install-package /' io-worker-deps-exclusion.txt) @@ -74,13 +57,13 @@ ADD extract_worker ./extract_worker/ ADD entrypoints/io_worker.sh ./entrypoints/io_worker.sh # Then install service -RUN --mount=type=cache,target=~/.cache/uv uv sync -v --frozen --no-editable $(sed 's/^/--no-install-package /' io-worker-deps-exclusion.txt) +RUN --mount=type=cache,target=/root/.cache/uv uv sync -v --frozen --no-editable $(sed 's/^/--no-install-package /' io-worker-deps-exclusion.txt) RUN rm -rf ~/.cache/pip ENTRYPOINT ["entrypoints/io_worker.sh"] -FROM extract-worker-builder AS extract-base-builder +FROM runtime-base AS extract-base-builder RUN apt update && \ apt install -y --no-install-recommends build-essential g++ && \ @@ -88,9 +71,9 @@ RUN apt update && \ rm -rf /var/lib/apt/lists/* -FROM extract-base-builder AS extract-cpu-worker +FROM extract-base-builder AS extract-cpu-build # Install deps first to optimize layer cache -RUN --mount=type=cache,target=~/.cache/uv \ +RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.dist.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ uv sync -v --frozen --no-editable --no-install-project --extra base --extra cpu @@ -102,23 +85,30 @@ ADD extract_worker ./extract_worker/ ADD entrypoints/extract_cpu_worker.sh ./entrypoints/extract_cpu_worker.sh # Then install service -RUN --mount=type=cache,target=~/.cache/uv uv sync -v --frozen --no-editable --extra base --extra cpu +RUN --mount=type=cache,target=/root/.cache/uv uv sync -v --frozen --no-editable --extra base --extra cpu RUN rm -rf ~/.cache/pip +# Slim runtime: drop build-essential/g++ (only needed to build the venv), keep tesseract for OCR +FROM runtime-base AS extract-cpu-worker +RUN apt update && \ + apt install -y --no-install-recommends tesseract-ocr && \ + rm -rf /var/lib/apt/lists/* +COPY --from=extract-cpu-build /app /app + ENTRYPOINT ["entrypoints/extract_cpu_worker.sh"] -FROM extract-base-builder AS extract-gpu-worker +FROM extract-base-builder AS extract-gpu-build ## Copy the flash-attn wheel #COPY --from=flash-attn-builder /flash-attn-wheel /flash-attn-wheel ## Install the wheel #RUN uv pip install /flash-attn-wheel/*.whl --no-deps # Install deps first to optimize layer cache -RUN --mount=type=cache,target=~/.cache/uv \ +RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.dist.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ - uv sync -v --frozen --no-editable --no-install-project --extra base --extra base --extra gpu #--no-install-package flash-attn + uv sync -v --frozen --no-editable --no-install-project --extra base --extra gpu # Then copy code ADD uv.dist.lock ./uv.lock @@ -127,15 +117,22 @@ ADD extract_worker ./extract_worker/ ADD entrypoints/extract_gpu_worker.sh ./entrypoints/extract_gpu_worker.sh # Then install service -RUN --mount=type=cache,target=~/.cache/uv uv sync -v --frozen --no-editable --extra base --extra gpu +RUN --mount=type=cache,target=/root/.cache/uv uv sync -v --frozen --no-editable --extra base --extra gpu RUN rm -rf ~/.cache/pip +# Slim runtime (as extract-cpu-worker): no toolchain, keep tesseract +FROM runtime-base AS extract-gpu-worker +RUN apt update && \ + apt install -y --no-install-recommends tesseract-ocr && \ + rm -rf /var/lib/apt/lists/* +COPY --from=extract-gpu-build /app /app + ENTRYPOINT ["entrypoints/extract_gpu_worker.sh"] -FROM extract-worker-builder AS extract-cpu-mineru-worker +FROM runtime-base AS extract-cpu-mineru-worker # Install deps first to optimize layer cache -RUN --mount=type=cache,target=~/.cache/uv \ +RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.dist.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ uv sync -v --frozen --no-editable --no-install-project --extra mineru --extra cpu @@ -147,18 +144,18 @@ ADD extract_worker ./extract_worker/ ADD entrypoints/extract_cpu_worker.sh ./entrypoints/extract_cpu_worker.sh # Then install service -RUN --mount=type=cache,target=~/.cache/uv uv sync -v --frozen --no-editable --extra mineru --extra cpu +RUN --mount=type=cache,target=/root/.cache/uv uv sync -v --frozen --no-editable --extra mineru --extra cpu RUN rm -rf ~/.cache/pip ENTRYPOINT ["entrypoints/extract_cpu_worker.sh"] -FROM extract-worker-builder AS extract-gpu-mineru-worker +FROM runtime-base AS extract-gpu-mineru-worker # Install deps first to optimize layer cache -RUN --mount=type=cache,target=~/.cache/uv \ +RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.dist.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ - uv sync -v --frozen --no-editable --no-install-project --extra mineru --extra mineru --extra gpu + uv sync -v --frozen --no-editable --no-install-project --extra mineru --extra gpu # Then copy code ADD uv.dist.lock ./uv.lock @@ -167,7 +164,7 @@ ADD extract_worker ./extract_worker/ ADD entrypoints/extract_gpu_worker.sh ./entrypoints/extract_gpu_worker.sh # Then install service -RUN --mount=type=cache,target=~/.cache/uv uv sync -v --frozen --no-editable --extra mineru --extra mineru --extra gpu +RUN --mount=type=cache,target=/root/.cache/uv uv sync -v --frozen --no-editable --extra mineru --extra gpu RUN rm -rf ~/.cache/pip ENTRYPOINT ["entrypoints/extract_gpu_worker.sh"] diff --git a/workers/extract-worker/base-worker-deps-exclusion.txt b/workers/extract-worker/base-worker-deps-exclusion.txt new file mode 100644 index 0000000..2c7137c --- /dev/null +++ b/workers/extract-worker/base-worker-deps-exclusion.txt @@ -0,0 +1,5 @@ +loguru +colorlog +httpx-retries +aiofiles +xlsxwriter