docling-studio/document-parser/Dockerfile
Pier-Jean Malandrino 0b544bdaef chore(#254): slim latest-local image (multi-stage + opt-in reasoning)
- Move docling-agent + mellea out of requirements.txt into a dedicated
  requirements-reasoning.txt. They are no longer pulled into latest-remote
  (regression fix) nor into latest-local by default.
- Dockerfile: split into builder-remote / builder-local / runtime-base
  stages. The runtime image carries no pip and no build cache; the source
  is COPYed only in the final stages so a code-only change reuses every
  pip-install layer.
- Add WITH_REASONING build-arg (default false) on the local target. Set to
  true to bundle the R&D reasoning-trace deps for a local-reasoning image.
- Harden .dockerignore: tests/, data/, uploads/, IDE files, stray
  node_modules / package-lock.json, the one-shot migrate_06.py utility.
- Set HF_HOME so the Docling/HF model cache lands in a deterministic
  appuser-owned path that compose can mount as a volume.
2026-05-11 09:38:32 +02:00

101 lines
3.5 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
COPY --chown=appuser:appuser . /app
ENV CONVERSION_ENGINE=local