########## Frontend build stage ########## FROM node:20-alpine AS frontend WORKDIR /frontend # Install dependencies and build COPY frontend/package*.json ./ RUN npm ci COPY frontend/ . # Allow overriding API base at build time if needed ARG VITE_API_BASE_URL= ENV VITE_API_BASE_URL=${VITE_API_BASE_URL} RUN npm run build ########## Backend runtime stage ########## FROM python:3.10-slim WORKDIR /app # Install system dependencies RUN apt-get update && apt-get install -y \ build-essential \ libgl1 \ libglib2.0-0 \ pandoc \ libreoffice \ fonts-noto \ fonts-noto-cjk \ && rm -rf /var/lib/apt/lists/* # Copy backend requirements and install COPY docling/requirements.txt ./requirements.txt ARG PIP_INDEX_URL RUN if [ -n "$PIP_INDEX_URL" ]; then pip install --no-cache-dir -i "$PIP_INDEX_URL" --timeout 120 -r requirements.txt; else pip install --no-cache-dir --timeout 120 -r requirements.txt; fi # Copy backend code COPY docling/ /app/docling/ # Copy built frontend into expected location COPY --from=frontend /frontend/dist /app/frontend/dist # Prefetch models for offline use ENV DOCLING_CACHE_DIR=/root/.cache/docling ENV PYTHONPATH=/app:/app/docling:/app/docling/docling RUN python - <<'PY' from docling.utils.model_downloader import download_models print('Prefetching Docling models (layout, table, picture-classifier, code-formula, rapidocr)...') download_models(progress=False) print('Models downloaded.') PY # Expose port ENV PORT=8000 EXPOSE 8000 # Start backend (serves API and /ui) CMD ["uvicorn", "app.server:app", "--host", "0.0.0.0", "--port", "8000"]