FROM ubuntu:24.04 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ python3.12 python3.12-venv python3.12-dev python3-pip \ libpoppler-cpp-dev poppler-utils \ libgl1 libglib2.0-0 \ build-essential curl \ && rm -rf /var/lib/apt/lists/* 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 ./ # Remaining dependencies resolve against the CPU torch already present. RUN . .venv/bin/activate && \ uv pip install "sentence-transformers[onnx]" && \ uv pip install -e . ENV PATH="/app/.venv/bin:$PATH" ENV VIRTUAL_ENV="/app/.venv" ENV KB_DEVICE=cpu ENV KB_INGEST_DEVICE=cpu ENV KB_DATA_DIR=/data EXPOSE 8000 VOLUME ["/data"] CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]