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.
This commit is contained in:
parent
38da579103
commit
0b544bdaef
4 changed files with 108 additions and 36 deletions
|
|
@ -10,3 +10,25 @@ __pycache__/
|
|||
.mypy_cache/
|
||||
.pytest_cache/
|
||||
.ruff_cache/
|
||||
|
||||
# Test + dev assets — never needed in the runtime image.
|
||||
tests/
|
||||
conftest.py
|
||||
pytest.ini
|
||||
requirements-test.txt
|
||||
|
||||
# Local runtime data — must not leak into the image.
|
||||
data/
|
||||
uploads/
|
||||
|
||||
# One-shot migration utility — runs out-of-band, not from the image.
|
||||
tools/migrate_06.py
|
||||
|
||||
# IDE / editor metadata.
|
||||
*.iml
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# Stray frontend artefacts that have no business inside document-parser/.
|
||||
package-lock.json
|
||||
node_modules/
|
||||
|
|
|
|||
|
|
@ -1,56 +1,101 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
# =============================================================================
|
||||
# Docling Studio — backend image (multi-target: remote / local)
|
||||
# Docling Studio — backend image (multi-stage, multi-target: remote / local)
|
||||
#
|
||||
# Usage:
|
||||
# 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).
|
||||
# =============================================================================
|
||||
|
||||
# --- Base: common deps for both targets ---
|
||||
FROM python:3.12-slim AS base
|
||||
# --- 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 \
|
||||
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
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN useradd --create-home --shell /bin/bash appuser \
|
||||
&& mkdir -p /app/uploads /app/data \
|
||||
&& chown -R appuser:appuser /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
|
||||
|
||||
ENV UPLOAD_DIR=/app/uploads
|
||||
ENV DB_PATH=/app/data/docling_studio.db
|
||||
|
||||
USER appuser
|
||||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
|
||||
# --- Remote: lightweight, delegates to Docling Serve ---
|
||||
FROM base AS remote
|
||||
# --- 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
|
||||
|
||||
# --- Local: full Docling in-process ---
|
||||
FROM base AS local
|
||||
# --- Final: local ------------------------------------------------------------
|
||||
FROM runtime-base AS local
|
||||
|
||||
USER root
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libgl1 \
|
||||
libglib2.0-0 \
|
||||
libgl1 \
|
||||
libglib2.0-0 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY requirements-local.txt .
|
||||
RUN pip install --no-cache-dir torch torchvision --index-url https://download.pytorch.org/whl/cpu \
|
||||
&& pip install --no-cache-dir -r requirements-local.txt
|
||||
|
||||
RUN chown -R appuser:appuser /app \
|
||||
&& chown -R appuser:appuser /usr/local/lib/python3.12/site-packages/rapidocr/models
|
||||
USER appuser
|
||||
|
||||
COPY --from=builder-local --chown=appuser:appuser /opt/venv /opt/venv
|
||||
COPY --chown=appuser:appuser . /app
|
||||
ENV CONVERSION_ENGINE=local
|
||||
|
|
|
|||
11
document-parser/requirements-reasoning.txt
Normal file
11
document-parser/requirements-reasoning.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# R&D reasoning-trace live runner — calls docling-agent's `_rag_loop` over
|
||||
# an Ollama backend. Gated server-side by `REASONING_ENABLED`; pulls a
|
||||
# heavy transitive set (mellea + pydantic-ai + several LLM SDKs).
|
||||
#
|
||||
# Opt in at build time with `--build-arg WITH_REASONING=true` on the
|
||||
# `local` Dockerfile target. Default off keeps the standard image lean.
|
||||
#
|
||||
# See https://github.com/docling-project/docling-agent/issues/26 for the
|
||||
# public-API replacement of `_rag_loop`.
|
||||
docling-agent==0.1.0
|
||||
mellea==0.4.2
|
||||
|
|
@ -9,9 +9,3 @@ httpx>=0.27.0,<1.0.0
|
|||
pypdfium2>=4.0.0,<5.0.0
|
||||
opensearch-py[async]>=2.6.0,<3.0.0
|
||||
neo4j>=5.15.0,<6.0.0
|
||||
# R&D reasoning-trace live runner — calls docling-agent's `_rag_loop` over
|
||||
# an Ollama backend. Gated server-side by `REASONING_ENABLED`; pulls ~60MB
|
||||
# of deps. See https://github.com/docling-project/docling-agent/issues/26 for
|
||||
# the public-API replacement of `_rag_loop`.
|
||||
docling-agent==0.1.0
|
||||
mellea==0.4.2
|
||||
|
|
|
|||
Loading…
Reference in a new issue