Split the torch layer and drop 7.8GB of orphaned CUDA libs from the CPU image
The CPU image was 11.2GB — larger than the CUDA one — and its single 6.72GB torch layer could not be pushed at all: the registry drops any blob upload taking longer than 60s, and that layer needed ~61s. Both problems came from install ordering. Dockerfile.cpu installed the project and sentence-transformers first, which resolved the default CUDA torch and pulled ~2.7GB of nvidia-* wheels, then reinstalled torch from the CPU index. Reinstalling replaces torch but leaves its transitive CUDA dependencies behind, orphaned and unused (torch reports 2.13.0+cpu, cuda.is_available() False). Installing CPU torch first, from the CPU index, means nothing ever requests a CUDA build. Everything else then resolves against the torch already present. CPU image 11.2GB -> 3.43GB largest layer 6.72GB -> 896MB push failed 5/5 at 60s -> succeeds in 8.6s Dockerfile.nvidia gets the same split. Its torch layer is unavoidably large (~2.8GiB compressed, ~52s at current throughput) so it stays the tightest thing in the stack, but splitting the application install off keeps that layer cached and the app layer small. Both now install torch before the source COPYs, so editing application code no longer invalidates the multi-GB layer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+20
-4
@@ -13,16 +13,32 @@ COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install CPU torch first, on its own, from the CPU index.
|
||||
#
|
||||
# Order matters: anything that depends on torch (sentence-transformers) will
|
||||
# otherwise resolve the default CUDA build and pull ~2.7GB of nvidia-* wheels.
|
||||
# Reinstalling torch afterwards replaces torch but leaves those wheels behind,
|
||||
# orphaned and unused — which is how the CPU image ended up larger than the
|
||||
# CUDA one. Installing CPU torch up front means nothing ever requests CUDA.
|
||||
#
|
||||
# Keeping it in its own layer also bounds the blob size: the registry drops
|
||||
# uploads that take longer than 60s, so no single layer should approach ~3GB.
|
||||
# Placing it before the source COPYs keeps this expensive layer cached when
|
||||
# only application code changes.
|
||||
RUN uv venv .venv && \
|
||||
. .venv/bin/activate && \
|
||||
UV_HTTP_TIMEOUT=600 uv pip install torch torchvision \
|
||||
--index-url https://download.pytorch.org/whl/cpu
|
||||
|
||||
COPY pyproject.toml ./
|
||||
COPY kb/ kb/
|
||||
COPY main.py ./
|
||||
COPY VERSION ./
|
||||
|
||||
RUN uv venv .venv && \
|
||||
. .venv/bin/activate && \
|
||||
uv pip install -e . && \
|
||||
# Remaining dependencies resolve against the CPU torch already present.
|
||||
RUN . .venv/bin/activate && \
|
||||
uv pip install "sentence-transformers[onnx]" && \
|
||||
uv pip install --reinstall torch torchvision --index-url https://download.pytorch.org/whl/cpu
|
||||
uv pip install -e .
|
||||
|
||||
ENV PATH="/app/.venv/bin:$PATH"
|
||||
ENV VIRTUAL_ENV="/app/.venv"
|
||||
|
||||
Reference in New Issue
Block a user