Eliminates the ~1.3 GB cold-start download on the first conversion. The new BAKE_MODELS build-arg defaults to true; pass --build-arg BAKE_MODELS=false to skip and keep the smaller 1.9 GB image when the deployment can tolerate a slow first run. Drop the hf_cache volume from compose — a named-volume mount on top of the baked path would mask the prefetched models with an empty volume on first 'docker compose up'. The image is now self-contained. Measured on arm64: - latest-local without bake : 1.89 GB - latest-local WITH bake : 3.19 GB (still -48% vs 6.09 GB baseline)
111 lines
3.8 KiB
Docker
111 lines
3.8 KiB
Docker
# syntax=docker/dockerfile:1
|
|
# =============================================================================
|
|
# Docling Studio — backend image (multi-stage, multi-target: remote / local)
|
|
#
|
|
# Standard usage:
|
|
# docker build --target remote -t docling-studio-backend:remote .
|
|
# docker build --target local -t docling-studio-backend:local .
|
|
#
|
|
# R&D variant — opt in to the reasoning-trace runner (docling-agent + mellea,
|
|
# heavy transitive deps; runtime-gated by REASONING_ENABLED):
|
|
# docker build --target local --build-arg WITH_REASONING=true \
|
|
# -t docling-studio-backend:local-reasoning .
|
|
#
|
|
# Cache notes:
|
|
# - Source is COPYed only in the final stages, never in the builders.
|
|
# A code-only change reuses every pip-install layer.
|
|
# - Each builder owns a venv at /opt/venv that the final stage copies in
|
|
# wholesale (no pip in the runtime image).
|
|
# =============================================================================
|
|
|
|
# --- Builder: remote (lightweight HTTP-only deps) ----------------------------
|
|
FROM python:3.12-slim AS builder-remote
|
|
|
|
ENV PIP_NO_CACHE_DIR=1 \
|
|
PIP_DISABLE_PIP_VERSION_CHECK=1
|
|
|
|
WORKDIR /build
|
|
RUN python -m venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
|
|
COPY requirements.txt .
|
|
RUN pip install -r requirements.txt
|
|
|
|
# --- Builder: local (torch CPU + full Docling, optional reasoning deps) ------
|
|
FROM python:3.12-slim AS builder-local
|
|
|
|
ENV PIP_NO_CACHE_DIR=1 \
|
|
PIP_DISABLE_PIP_VERSION_CHECK=1
|
|
|
|
WORKDIR /build
|
|
RUN python -m venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
|
|
COPY requirements.txt requirements-local.txt requirements-reasoning.txt ./
|
|
|
|
# torch CPU wheels in their own layer — pinned to the CPU-only index so the
|
|
# transitive resolution of docling does not re-pull a CUDA build.
|
|
RUN pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
|
|
|
|
# Full local stack (requirements-local.txt re-includes requirements.txt).
|
|
RUN pip install -r requirements-local.txt
|
|
|
|
# Reasoning is opt-in; off by default keeps the standard image lean.
|
|
ARG WITH_REASONING=false
|
|
RUN if [ "$WITH_REASONING" = "true" ]; then \
|
|
pip install -r requirements-reasoning.txt; \
|
|
fi
|
|
|
|
# --- Runtime base (no pip, no source — shared by both final targets) ---------
|
|
FROM python:3.12-slim AS runtime-base
|
|
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
poppler-utils \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
RUN useradd --create-home --shell /bin/bash appuser \
|
|
&& mkdir -p /app/uploads /app/data /home/appuser/.cache/huggingface \
|
|
&& chown -R appuser:appuser /app /home/appuser/.cache
|
|
|
|
WORKDIR /app
|
|
|
|
ENV PATH="/opt/venv/bin:$PATH" \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1 \
|
|
UPLOAD_DIR=/app/uploads \
|
|
DB_PATH=/app/data/docling_studio.db \
|
|
HF_HOME=/home/appuser/.cache/huggingface
|
|
|
|
EXPOSE 8000
|
|
USER appuser
|
|
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
|
|
# --- Final: remote -----------------------------------------------------------
|
|
FROM runtime-base AS remote
|
|
COPY --from=builder-remote --chown=appuser:appuser /opt/venv /opt/venv
|
|
COPY --chown=appuser:appuser . /app
|
|
ENV CONVERSION_ENGINE=remote
|
|
|
|
# --- Final: local ------------------------------------------------------------
|
|
FROM runtime-base AS local
|
|
|
|
USER root
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
libgl1 \
|
|
libglib2.0-0 \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
USER appuser
|
|
|
|
COPY --from=builder-local --chown=appuser:appuser /opt/venv /opt/venv
|
|
|
|
# Pre-fetch Docling model checkpoints into the appuser HF cache so the very
|
|
# first conversion does not pay the ~400 MB cold-start download. Opt out
|
|
# with --build-arg BAKE_MODELS=false for an even smaller image (will then
|
|
# download on first request).
|
|
ARG BAKE_MODELS=true
|
|
RUN if [ "$BAKE_MODELS" = "true" ]; then \
|
|
docling-tools models download; \
|
|
fi
|
|
|
|
COPY --chown=appuser:appuser . /app
|
|
ENV CONVERSION_ENGINE=local
|