From 926e7e5f765b25a919a773e836477076b39a3dc5 Mon Sep 17 00:00:00 2001 From: millaguie Date: Tue, 30 Jun 2026 12:45:12 +0200 Subject: [PATCH 1/5] refactor(extract-worker): correct cache path --- workers/extract-worker/Dockerfile | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/workers/extract-worker/Dockerfile b/workers/extract-worker/Dockerfile index 5d2ec6a..e43bf62 100644 --- a/workers/extract-worker/Dockerfile +++ b/workers/extract-worker/Dockerfile @@ -40,7 +40,7 @@ COPY --from=ghcr.io/astral-sh/uv:0.11.6 /uv /bin/ RUN uv python install 3.14t # 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,7 +53,7 @@ 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 @@ -62,7 +62,7 @@ RUN --mount=type=cache,target=~/.cache/uv \ FROM extract-worker-builder 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,7 +74,7 @@ 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"] @@ -90,7 +90,7 @@ RUN apt update && \ FROM extract-base-builder AS extract-cpu-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 base --extra cpu @@ -102,7 +102,7 @@ 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 ENTRYPOINT ["entrypoints/extract_cpu_worker.sh"] @@ -115,10 +115,10 @@ FROM extract-base-builder AS extract-gpu-worker #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 #--no-install-package flash-attn # Then copy code ADD uv.dist.lock ./uv.lock @@ -127,7 +127,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 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 ENTRYPOINT ["entrypoints/extract_gpu_worker.sh"] @@ -135,7 +135,7 @@ ENTRYPOINT ["entrypoints/extract_gpu_worker.sh"] FROM extract-worker-builder 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,7 +147,7 @@ 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"] @@ -155,10 +155,10 @@ ENTRYPOINT ["entrypoints/extract_cpu_worker.sh"] FROM extract-worker-builder 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 +167,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"] From 6221dfecc490f75e84071b49d94f1afffa84c714 Mon Sep 17 00:00:00 2001 From: millaguie Date: Wed, 1 Jul 2026 11:45:35 +0200 Subject: [PATCH 2/5] refactor(extract-worker): slim base images (split runtime, drop mineru) --- workers/extract-worker/.dockerignore | 3 +- workers/extract-worker/Dockerfile | 53 +++++++++++++++---- .../base-worker-deps-exclusion.txt | 15 ++++++ 3 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 workers/extract-worker/base-worker-deps-exclusion.txt diff --git a/workers/extract-worker/.dockerignore b/workers/extract-worker/.dockerignore index f1c3a14..9863aae 100644 --- a/workers/extract-worker/.dockerignore +++ b/workers/extract-worker/.dockerignore @@ -5,4 +5,5 @@ !README.md !uv.dist.lock !uv.lock -!io-worker-deps-exclusion.txt \ No newline at end of file +!io-worker-deps-exclusion.txt +!base-worker-deps-exclusion.txt diff --git a/workers/extract-worker/Dockerfile b/workers/extract-worker/Dockerfile index e43bf62..57db9fa 100644 --- a/workers/extract-worker/Dockerfile +++ b/workers/extract-worker/Dockerfile @@ -17,7 +17,6 @@ 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 \ @@ -26,7 +25,21 @@ RUN apt install -y git-all \ zlib1g-dev COPY --from=ghcr.io/astral-sh/uv:0.11.24 /uv /uvx /bin/ -RUN uv python install 3.14t +RUN uv python install 3.14 + +WORKDIR /app + +# 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_NO_DEV=1 + +COPY --from=ghcr.io/astral-sh/uv:0.11.24 /uv /uvx /bin/ +COPY --from=extract-worker-builder /root/.local/share/uv/python /root/.local/share/uv/python WORKDIR /app @@ -37,7 +50,7 @@ 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=/root/.cache/uv \ @@ -88,12 +101,15 @@ 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 +# Skip the mineru-only subtree: extract-core pulls mineru unconditionally, but docling/marker don't use it (and it conflicts with marker) +ADD base-worker-deps-exclusion.txt ./ # Install deps first to optimize layer cache 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 + uv sync -v --frozen --no-editable --no-install-project --extra base --extra cpu \ + $(sed 's/^/--no-install-package /' base-worker-deps-exclusion.txt) # Then copy code ADD uv.dist.lock ./uv.lock @@ -102,23 +118,34 @@ ADD extract_worker ./extract_worker/ ADD entrypoints/extract_cpu_worker.sh ./entrypoints/extract_cpu_worker.sh # Then install service -RUN --mount=type=cache,target=/root/.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 \ + $(sed 's/^/--no-install-package /' base-worker-deps-exclusion.txt) 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 +# Skip the mineru-only subtree: extract-core pulls mineru unconditionally, but docling/marker don't use it (and it conflicts with marker). +ADD base-worker-deps-exclusion.txt ./ # Install deps first to optimize layer cache 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 gpu #--no-install-package flash-attn + uv sync -v --frozen --no-editable --no-install-project --extra base --extra gpu \ + $(sed 's/^/--no-install-package /' base-worker-deps-exclusion.txt) #--no-install-package flash-attn # Then copy code ADD uv.dist.lock ./uv.lock @@ -127,9 +154,17 @@ ADD extract_worker ./extract_worker/ ADD entrypoints/extract_gpu_worker.sh ./entrypoints/extract_gpu_worker.sh # Then install service -RUN --mount=type=cache,target=/root/.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 \ + $(sed 's/^/--no-install-package /' base-worker-deps-exclusion.txt) 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"] 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..3d68265 --- /dev/null +++ b/workers/extract-worker/base-worker-deps-exclusion.txt @@ -0,0 +1,15 @@ +mineru +mineru-vl-utils +modelscope +magika +reportlab +pypdf +fast-langdetect +fasttext-predict +json-repair +robust-downloader +loguru +colorlog +httpx-retries +aiofiles +xlsxwriter From bfc42eef5e3ecdaac728fc84022bf60231915755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Doumouro?= Date: Wed, 15 Jul 2026 13:22:18 +0200 Subject: [PATCH 3/5] chore(extract-worker): remove base-worker-deps-exclusion since excluded deps are no longer in the `uv.dist.lock` after deps update --- workers/extract-worker/.dockerignore | 1 - workers/extract-worker/Dockerfile | 16 ++++------------ .../base-worker-deps-exclusion.txt | 10 ---------- 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/workers/extract-worker/.dockerignore b/workers/extract-worker/.dockerignore index 9863aae..e1222e7 100644 --- a/workers/extract-worker/.dockerignore +++ b/workers/extract-worker/.dockerignore @@ -6,4 +6,3 @@ !uv.dist.lock !uv.lock !io-worker-deps-exclusion.txt -!base-worker-deps-exclusion.txt diff --git a/workers/extract-worker/Dockerfile b/workers/extract-worker/Dockerfile index 57db9fa..8500a4a 100644 --- a/workers/extract-worker/Dockerfile +++ b/workers/extract-worker/Dockerfile @@ -102,14 +102,11 @@ RUN apt update && \ FROM extract-base-builder AS extract-cpu-build -# Skip the mineru-only subtree: extract-core pulls mineru unconditionally, but docling/marker don't use it (and it conflicts with marker) -ADD base-worker-deps-exclusion.txt ./ # Install deps first to optimize layer cache 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 \ - $(sed 's/^/--no-install-package /' base-worker-deps-exclusion.txt) + uv sync -v --frozen --no-editable --no-install-project --extra base --extra cpu # Then copy code ADD uv.dist.lock ./uv.lock @@ -118,8 +115,7 @@ ADD extract_worker ./extract_worker/ ADD entrypoints/extract_cpu_worker.sh ./entrypoints/extract_cpu_worker.sh # Then install service -RUN --mount=type=cache,target=/root/.cache/uv uv sync -v --frozen --no-editable --extra base --extra cpu \ - $(sed 's/^/--no-install-package /' base-worker-deps-exclusion.txt) +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 @@ -138,14 +134,11 @@ FROM extract-base-builder AS extract-gpu-build ## Install the wheel #RUN uv pip install /flash-attn-wheel/*.whl --no-deps -# Skip the mineru-only subtree: extract-core pulls mineru unconditionally, but docling/marker don't use it (and it conflicts with marker). -ADD base-worker-deps-exclusion.txt ./ # Install deps first to optimize layer cache 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 gpu \ - $(sed 's/^/--no-install-package /' base-worker-deps-exclusion.txt) #--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 @@ -154,8 +147,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=/root/.cache/uv uv sync -v --frozen --no-editable --extra base --extra gpu \ - $(sed 's/^/--no-install-package /' base-worker-deps-exclusion.txt) +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 diff --git a/workers/extract-worker/base-worker-deps-exclusion.txt b/workers/extract-worker/base-worker-deps-exclusion.txt index 3d68265..2c7137c 100644 --- a/workers/extract-worker/base-worker-deps-exclusion.txt +++ b/workers/extract-worker/base-worker-deps-exclusion.txt @@ -1,13 +1,3 @@ -mineru -mineru-vl-utils -modelscope -magika -reportlab -pypdf -fast-langdetect -fasttext-predict -json-repair -robust-downloader loguru colorlog httpx-retries From 8e5077705e9a359771103667ec3675c86b25036a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Doumouro?= Date: Wed, 15 Jul 2026 14:49:50 +0200 Subject: [PATCH 4/5] chore(extract-worker): compile bytecode by default --- workers/extract-worker/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/workers/extract-worker/Dockerfile b/workers/extract-worker/Dockerfile index 8500a4a..0e8ec4b 100644 --- a/workers/extract-worker/Dockerfile +++ b/workers/extract-worker/Dockerfile @@ -36,6 +36,7 @@ WORKDIR /app FROM debian:trixie-slim AS runtime-base ENV PYTHONUNBUFFERED=1 +ENV UV_COMPILE_BYTECODE=1 ENV UV_NO_DEV=1 COPY --from=ghcr.io/astral-sh/uv:0.11.24 /uv /uvx /bin/ From 573481b92096f7d4b7faa782601cc65bda4c2e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Doumouro?= Date: Wed, 15 Jul 2026 14:59:10 +0200 Subject: [PATCH 5/5] chore(extract-worker): use uv copy mode for links to optimize perfs --- workers/extract-worker/Dockerfile | 41 ++++--------------------------- 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/workers/extract-worker/Dockerfile b/workers/extract-worker/Dockerfile index 0e8ec4b..39d3f50 100644 --- a/workers/extract-worker/Dockerfile +++ b/workers/extract-worker/Dockerfile @@ -1,34 +1,3 @@ -FROM python:3.14-slim-trixie AS extract-worker-builder - -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 - -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.14 - -WORKDIR /app - # 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 @@ -37,10 +6,10 @@ FROM debian:trixie-slim AS runtime-base ENV PYTHONUNBUFFERED=1 ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy ENV UV_NO_DEV=1 COPY --from=ghcr.io/astral-sh/uv:0.11.24 /uv /uvx /bin/ -COPY --from=extract-worker-builder /root/.local/share/uv/python /root/.local/share/uv/python WORKDIR /app @@ -73,7 +42,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \ --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=/root/.cache/uv \ @@ -94,7 +63,7 @@ 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++ && \ @@ -161,7 +130,7 @@ 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=/root/.cache/uv \ --mount=type=bind,source=uv.dist.lock,target=uv.lock \ @@ -181,7 +150,7 @@ 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=/root/.cache/uv \ --mount=type=bind,source=uv.dist.lock,target=uv.lock \