mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
992224f2e8
Generate a synced read-aloud EPUB from a book's EPUB and audiobook through an optional STAlign worker (Docker on CPU, or native with MLX on Apple Silicon), with review, re-sync, replace in place, restart recovery and live progress on the Files tab. Book details also stack the ebook and audiobook covers when both exist. See docs/READ_ALOUD.md.
69 lines
3.3 KiB
Docker
69 lines
3.3 KiB
Docker
# Debian trixie for ffmpeg 7: STAlign's audiobook probe passes `ffprobe -output_format`, which the
|
|
# ffmpeg 5.1 in bookworm rejects, failing every job in its first stage.
|
|
ARG NODE_IMAGE=node:26.8.1-trixie-slim
|
|
|
|
FROM ${NODE_IMAGE} AS builder
|
|
WORKDIR /app
|
|
RUN npm install -g pnpm@11.22.0
|
|
|
|
# The image runs on CPU only: without this, onnxruntime-node downloads its CUDA provider on
|
|
# linux/x64, which cannot load here (no CUDA or cuDNN libraries) and only adds size.
|
|
ENV ONNXRUNTIME_NODE_INSTALL=skip
|
|
|
|
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./
|
|
COPY patches/ ./patches/
|
|
COPY packages/types/package.json ./packages/types/
|
|
COPY workers/read-aloud/package.json ./workers/read-aloud/
|
|
RUN --mount=type=cache,id=pnpm-read-aloud,target=/root/.local/share/pnpm/store \
|
|
pnpm install --filter @bookorbit/read-aloud-worker... --frozen-lockfile
|
|
|
|
COPY packages/types/ ./packages/types/
|
|
COPY workers/read-aloud/ ./workers/read-aloud/
|
|
RUN pnpm --config.verify-deps-before-run=false --filter @bookorbit/types build && \
|
|
pnpm --config.verify-deps-before-run=false --filter @bookorbit/read-aloud-worker build && \
|
|
pnpm --config.allow-unused-patches=true --filter @bookorbit/read-aloud-worker deploy --prod --legacy /deploy && \
|
|
rm -rf /deploy/dist /deploy/assets && \
|
|
cp -r /app/workers/read-aloud/dist /app/workers/read-aloud/assets /deploy/ && \
|
|
types_dir="$(dirname "$(cd /deploy && node -p 'require.resolve("@bookorbit/types/package.json")')")" && \
|
|
rm -rf "$types_dir/dist" && cp -r /app/packages/types/dist "$types_dir/dist" && \
|
|
cd /deploy && node -e 'require("@bookorbit/types").READ_ALOUD_WORKER_PROTOCOL || process.exit(1)' && \
|
|
find node_modules/.pnpm/onnxruntime-node@*/node_modules/onnxruntime-node/bin/napi-v6 -mindepth 1 -maxdepth 1 ! -name linux -exec rm -rf {} +
|
|
|
|
# Speech models reach the data volume (XDG_DATA_HOME) only through the ghost-story patch; without it
|
|
# they go to the home folder, which is read-only under Compose, and every model download fails.
|
|
RUN cd /deploy && \
|
|
patched="$(find node_modules/.pnpm -path '*/node_modules/@storyteller-platform/ghost-story/dist/utilities/FileSystem.js')" && \
|
|
if [ -z "$patched" ] || grep -L 'process.env\["XDG_DATA_HOME"\]' $patched | grep -q .; then \
|
|
echo "ghost-story in the image lacks patches/@storyteller-platform__ghost-story@0.3.4.patch" >&2; exit 1; \
|
|
fi
|
|
|
|
FROM ${NODE_IMAGE} AS runtime
|
|
WORKDIR /app
|
|
RUN apt-get update && \
|
|
apt-get install -y --no-install-recommends ca-certificates ffmpeg tini && \
|
|
rm -rf /var/lib/apt/lists/* && \
|
|
mkdir -p /data/read-aloud/jobs /data/read-aloud/tmp /data/read-aloud/ghost-story && \
|
|
chown -R node:node /data
|
|
|
|
ENV NODE_ENV=production
|
|
ENV PORT=8787
|
|
ENV READ_ALOUD_WORKER_HOST=0.0.0.0
|
|
ENV READ_ALOUD_LIBRARY_ROOTS=/books
|
|
ENV READ_ALOUD_WORK_ROOT=/data/read-aloud/jobs
|
|
ENV READ_ALOUD_TMP_DIR=/data/read-aloud/tmp
|
|
ENV READ_ALOUD_CTC_DEVICE=auto
|
|
ENV TMPDIR=/data/read-aloud/tmp
|
|
ENV XDG_DATA_HOME=/data/read-aloud
|
|
|
|
COPY --from=builder --chown=node:node /deploy ./
|
|
COPY --chown=node:node server/file-env.sh workers/read-aloud/entrypoint.sh ./
|
|
RUN chmod +x /app/entrypoint.sh
|
|
|
|
# The release this image was built from, reported in health; unset falls back to the package version.
|
|
ARG APP_VERSION
|
|
ENV APP_VERSION=${APP_VERSION}
|
|
|
|
USER node
|
|
EXPOSE 8787
|
|
ENTRYPOINT ["/usr/bin/tini", "--", "/app/entrypoint.sh"]
|