Migrate PDF parsing to use ONNX Docling layout model for structured block extraction, enabling improved TTS segmentation and chaptering. Add compute backend abstraction for heavy tasks (alignment, layout parsing) with configuration via `OPENREADER_COMPUTE_MODE`. Integrate block-level locators and document settings for per-document PDF parsing options. Update S3 storage for parsed PDF JSON, add migration and schema changes, and extend client and server APIs for parsed data and settings. Remove legacy word highlight flag in favor of compute capability detection. - Add ONNX model download, local/none compute modes, and `onnxruntime-node` dependency - Update PDF viewer and TTS pipeline to use parsed blocks and block-level locators - Add document settings storage and APIs for per-document PDF options - Update S3 storage layout for parsed PDF JSON - Add admin/config/docs updates for new compute and parsing features - Remove obsolete word highlight runtime flag and UI BREAKING CHANGE: PDF parsing and word highlighting now require `OPENREADER_COMPUTE_MODE=local` and ONNX model; document settings and S3 layout updated; legacy word highlight flag removed.
95 lines
3.5 KiB
Docker
95 lines
3.5 KiB
Docker
# Stage 1: build whisper.cpp (no model download – the app handles that)
|
||
FROM alpine:3.23 AS whisper-builder
|
||
|
||
RUN apk add --no-cache git cmake build-base
|
||
|
||
WORKDIR /opt
|
||
|
||
ARG TARGETARCH
|
||
|
||
RUN git clone --depth 1 https://github.com/ggml-org/whisper.cpp.git && \
|
||
cd whisper.cpp && \
|
||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DGGML_NATIVE=OFF $( [ "$TARGETARCH" = "arm64" ] && echo "-DGGML_CPU_ARM_ARCH=armv8-a" || true ) && \
|
||
cmake --build build -j
|
||
RUN wget -qO /tmp/whisper.cpp-LICENSE.txt "https://raw.githubusercontent.com/ggml-org/whisper.cpp/master/LICENSE"
|
||
|
||
# Stage 1b: extract seaweedfs weed binary (for optional embedded weed mini)
|
||
# Pin to 4.18 because CI observed upload regressions on 4.19.
|
||
FROM chrislusf/seaweedfs:4.18 AS seaweedfs-builder
|
||
RUN cp "$(command -v weed)" /tmp/weed && \
|
||
(wget -qO /tmp/SeaweedFS-LICENSE.txt "https://raw.githubusercontent.com/seaweedfs/seaweedfs/master/LICENSE" || \
|
||
wget -qO /tmp/SeaweedFS-LICENSE.txt "https://raw.githubusercontent.com/seaweedfs/seaweedfs/main/LICENSE")
|
||
|
||
|
||
# Stage 2: build the Next.js app
|
||
FROM node:lts-alpine AS app-builder
|
||
|
||
# Install pnpm globally
|
||
RUN npm install -g pnpm@11.1.2
|
||
|
||
# Create app directory
|
||
WORKDIR /app
|
||
|
||
# Copy package files
|
||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||
|
||
# Install dependencies
|
||
RUN pnpm install --frozen-lockfile
|
||
|
||
# Copy project files
|
||
COPY . .
|
||
|
||
# Build the Next.js application
|
||
RUN pnpm exec next telemetry disable
|
||
RUN pnpm build
|
||
# Generate third-party dependency license report plus copied license files.
|
||
RUN mkdir -p /app/THIRD_PARTY_LICENSES && \
|
||
pnpm dlx license-checker-rseidelsohn@4.3.0 \
|
||
--production \
|
||
--json \
|
||
--relativeLicensePath \
|
||
--out /app/THIRD_PARTY_LICENSES/licenses.json \
|
||
--files /app/THIRD_PARTY_LICENSES/files
|
||
|
||
|
||
# Stage 3: minimal runtime image
|
||
FROM node:lts-alpine AS runner
|
||
|
||
# Add runtime OS dependencies:
|
||
# - libreoffice-writer: required for DOCX → PDF conversion
|
||
# ffmpeg is provided by ffmpeg-static from node_modules.
|
||
RUN apk add --no-cache ca-certificates libreoffice-writer
|
||
|
||
# Install pnpm globally for running the app
|
||
RUN npm install -g pnpm@11.1.2
|
||
|
||
# App runtime directory
|
||
WORKDIR /app
|
||
|
||
# Copy built app and dependencies from the builder stage
|
||
COPY --from=app-builder /app ./
|
||
# Include third-party license report and copied license texts at a stable path in the image.
|
||
COPY --from=app-builder /app/THIRD_PARTY_LICENSES /licenses
|
||
# Include SeaweedFS license text for the copied weed binary.
|
||
COPY --from=seaweedfs-builder /tmp/SeaweedFS-LICENSE.txt /licenses/SeaweedFS-LICENSE.txt
|
||
# Include static model notices for runtime-downloaded assets.
|
||
COPY src/lib/server/pdf-layout/model/LICENSE.txt /licenses/docling-layout-LICENSE.txt
|
||
|
||
# Copy the compiled whisper.cpp build output into the runtime image
|
||
# (includes whisper-cli and its shared libraries, e.g. libwhisper.so, libggml.so)
|
||
COPY --from=whisper-builder /opt/whisper.cpp/build /opt/whisper.cpp/build
|
||
COPY --from=whisper-builder /tmp/whisper.cpp-LICENSE.txt /licenses/whisper.cpp-LICENSE.txt
|
||
# Copy seaweedfs weed binary for optional embedded local S3.
|
||
COPY --from=seaweedfs-builder /tmp/weed /usr/local/bin/weed
|
||
RUN chmod +x /usr/local/bin/weed
|
||
|
||
# Point the app at the compiled whisper-cli binary and ensure its libs are discoverable
|
||
ENV WHISPER_CPP_BIN=/opt/whisper.cpp/build/bin/whisper-cli
|
||
ENV LD_LIBRARY_PATH=/opt/whisper.cpp/build
|
||
|
||
# Expose the port the app runs on
|
||
EXPOSE 3003
|
||
|
||
# Start the application
|
||
ENTRYPOINT ["node", "scripts/openreader-entrypoint.mjs", "--"]
|
||
CMD ["pnpm", "start:raw"]
|