refactor(build): update Dockerfiles for improved dependency isolation and workspace handling

Remove legacy .npmrc config. Revise root and worker Dockerfiles to enhance
layer caching, explicitly copy only required build artifacts, and streamline
runtime dependencies. Switch to pnpm workspace-aware install for compute worker
to ensure correct dependency resolution. Set Next.js output to standalone mode
for optimized server builds. Update docker-compose sync targets for consistency.
This commit is contained in:
Richard R 2026-05-20 13:21:12 -06:00
parent b30304a119
commit 3a1dd41d91
5 changed files with 37 additions and 15 deletions

1
.npmrc
View file

@ -1 +0,0 @@
node-linker=hoisted

View file

@ -45,31 +45,45 @@ FROM node:lts-alpine AS runner
# ffmpeg is provided by ffmpeg-static from node_modules. # ffmpeg is provided by ffmpeg-static from node_modules.
RUN apk add --no-cache ca-certificates libreoffice-writer RUN apk add --no-cache ca-certificates libreoffice-writer
# Install pnpm globally for running the app # drizzle-kit is used by scripts/openreader-entrypoint.mjs for startup migrations.
RUN npm install -g pnpm@11.1.2 RUN npm install -g drizzle-kit@0.31.10
# App runtime directory # App runtime directory
WORKDIR /app WORKDIR /app
# Copy built app and dependencies from the builder stage # Entry-point and migration scripts import dotenv directly.
COPY --from=app-builder /app ./ RUN npm install --no-save dotenv@17.4.2
# Copy standalone Next.js server and required static assets.
COPY --from=app-builder /app/.next/standalone ./
COPY --from=app-builder /app/.next/static ./.next/static
COPY --from=app-builder /app/public ./public
# Copy startup/migration scripts and migration files used by openreader-entrypoint.
COPY --from=app-builder /app/scripts/openreader-entrypoint.mjs ./scripts/openreader-entrypoint.mjs
COPY --from=app-builder /app/scripts/migrate-fs-v2.mjs ./scripts/migrate-fs-v2.mjs
COPY --from=app-builder /app/drizzle/scripts/migrate.mjs ./drizzle/scripts/migrate.mjs
COPY --from=app-builder /app/drizzle/sqlite ./drizzle/sqlite
COPY --from=app-builder /app/drizzle/postgres ./drizzle/postgres
COPY --from=app-builder /app/drizzle.config.sqlite.ts ./drizzle.config.sqlite.ts
COPY --from=app-builder /app/drizzle.config.pg.ts ./drizzle.config.pg.ts
COPY --from=app-builder /app/src/db ./src/db
# Include third-party license report and copied license texts at a stable path in the image. # 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 COPY --from=app-builder /app/THIRD_PARTY_LICENSES /licenses
# Include SeaweedFS license text for the copied weed binary. # Include SeaweedFS license text for the copied weed binary.
COPY --from=seaweedfs-builder /tmp/SeaweedFS-LICENSE.txt /licenses/SeaweedFS-LICENSE.txt COPY --from=seaweedfs-builder /tmp/SeaweedFS-LICENSE.txt /licenses/SeaweedFS-LICENSE.txt
# Include static model notices for runtime-downloaded assets. # Include static model notices for runtime-downloaded assets.
COPY src/lib/server/pdf-layout/model/LICENSE.txt /licenses/pp-doclayoutv3-LICENSE.txt COPY --from=app-builder /app/src/lib/server/pdf-layout/model/LICENSE.txt /licenses/pp-doclayoutv3-LICENSE.txt
# Copy seaweedfs weed binary for optional embedded local S3. # Copy seaweedfs weed binary for optional embedded local S3.
COPY --from=seaweedfs-builder /tmp/weed /usr/local/bin/weed COPY --from=seaweedfs-builder /tmp/weed /usr/local/bin/weed
RUN chmod +x /usr/local/bin/weed RUN chmod +x /usr/local/bin/weed
# Include OpenAI Whisper license text for runtime-downloaded ONNX artifacts. # Include OpenAI Whisper license text for runtime-downloaded ONNX artifacts.
COPY src/lib/server/whisper/model/LICENSE.txt /licenses/openai-whisper-LICENSE.txt COPY --from=app-builder /app/src/lib/server/whisper/model/LICENSE.txt /licenses/openai-whisper-LICENSE.txt
# Expose the port the app runs on # Expose the port the app runs on
EXPOSE 3003 EXPOSE 3003
# Start the application # Start the application
ENTRYPOINT ["node", "scripts/openreader-entrypoint.mjs", "--"] ENTRYPOINT ["node", "scripts/openreader-entrypoint.mjs", "--"]
CMD ["pnpm", "start:raw"] CMD ["node", "server.js"]

View file

@ -1,4 +1,4 @@
FROM node:lts FROM node:lts AS deploy-stage
RUN npm install -g pnpm@11.1.2 RUN npm install -g pnpm@11.1.2
@ -8,13 +8,22 @@ COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY compute/worker/package.json compute/worker/package.json COPY compute/worker/package.json compute/worker/package.json
COPY compute/core/package.json compute/core/package.json COPY compute/core/package.json compute/core/package.json
RUN pnpm install --frozen-lockfile COPY compute/worker compute/worker
COPY compute/core compute/core
COPY . . RUN pnpm --config.inject-workspace-packages=true --filter @openreader/compute-worker deploy /opt/compute-worker
FROM node:lts
RUN npm install -g pnpm@11.1.2
WORKDIR /workspace
COPY --from=deploy-stage /opt/compute-worker ./
ENV COMPUTE_WORKER_HOST=0.0.0.0 ENV COMPUTE_WORKER_HOST=0.0.0.0
ENV COMPUTE_WORKER_PORT=8081 ENV COMPUTE_WORKER_PORT=8081
EXPOSE 8081 EXPOSE 8081
CMD ["pnpm", "--filter", "@openreader/compute-worker", "dev"] CMD ["pnpm", "dev"]

View file

@ -31,10 +31,9 @@ services:
watch: watch:
- action: sync+restart - action: sync+restart
path: . path: .
target: /workspace/compute/worker target: /workspace
- action: sync+restart - action: rebuild
path: ../../compute/core path: ../../compute/core
target: /workspace/compute/core
- action: rebuild - action: rebuild
path: ./package.json path: ./package.json
- action: rebuild - action: rebuild

View file

@ -28,6 +28,7 @@ const serverExternalPackages = [
]; ];
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
output: 'standalone',
async headers() { async headers() {
return [ return [
{ {