Files
bookorbit/workers/read-aloud/Dockerfile
T
neon f79874317d perf(koreader): check md5 before bcrypt when authenticating plugin requests
The KOReader plugin sends md5(password) as x-auth-key, which can never match the bcrypt hash of the
plaintext password. The auth guard ran a cost-12 bcrypt compare first, so every authenticated
request spent about 250 ms of CPU and stalled other traffic before the md5 fallback accepted it.

Check md5 first and keep bcrypt as the fallback for clients that send the plaintext password, so the
accepted credentials are unchanged. A plugin auth call drops from about 285 ms to 8 ms.

Bump the KOReader plugin to 2.2.0. The plugin changed after the 2.1.0 release shipped in v3.6.0
(series sorting, series selection, file browser exit, paged Shelves list) without a version bump.

Also fix three metadata-fetch tests that were failing on main since cfcd4ca52 kept single-digit
tokens in tokenizeTitleText. A volume digit in the query diluted the word overlap in scoreTitleMatch,
so an ebook candidate fell under the relevance floor and a manga outranked it. scoreTitleMatch now
drops lone digits again; symmetricTitleSimilarity keeps them to tell volumes apart.

Also align the pnpm version installed in both Dockerfiles with the packageManager field. Since
f2a7a1118 the images installed pnpm 11.22.0 while package.json pinned 11.28.9, so pnpm tried to
switch itself and failed the arm64 image build with a missing @pnpm/exe lockfile entry.

Closes #1983
Ref #2037
2026-11-02 04:54:35 +00:00

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.12.1-trixie-slim
FROM ${NODE_IMAGE} AS builder
WORKDIR /app
RUN npm install -g pnpm@11.28.9
# 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"]