# Standalone image for services/tech-step-llm-worker — deliberately *not* # built as part of apps/api's own Dockerfile/image (see this package's own # package.json doc comment): node-llama-cpp's native binding must never be # compiled into the API's image, and this worker shares no dependencies or # code with it (see api-client.ts's own doc comment on why its types are # duplicated rather than imported from @batch-cooking/shared). FROM node:22-slim AS base # node-llama-cpp's postinstall builds/downloads a native binding — basic # build tooling covers the (rare) case a prebuilt binary isn't available # for this platform; ca-certificates is needed for the HTTPS download of # both that binary and the GGUF model weights (resolveModelFile, # llm-verdict.ts). RUN apt-get update && apt-get install -y --no-install-recommends python3 make g++ ca-certificates && rm -rf /var/lib/apt/lists/* RUN corepack enable WORKDIR /worker FROM base AS build # `pnpm-lock.yaml` is committed for this package (unlike # experiments/llm-tech-step-poc, which has none) — `--frozen-lockfile` # means a build fails loudly on any drift instead of silently resolving # different versions than what's on disk/CI. COPY services/tech-step-llm-worker/package.json services/tech-step-llm-worker/pnpm-lock.yaml ./ RUN pnpm install --ignore-workspace --frozen-lockfile # tsconfig.json `extends` the repo-root base config (shared with every # other package's own tsconfig) — must be copied in alongside it, or `tsc` # fails outright (TS5083) before it ever reaches src. COPY tsconfig.base.json ../tsconfig.base.json COPY services/tech-step-llm-worker/tsconfig.json ./tsconfig.json COPY services/tech-step-llm-worker/src ./src RUN pnpm exec tsc -p tsconfig.json FROM base AS runtime ENV NODE_ENV=production COPY --from=build /worker/node_modules ./node_modules COPY --from=build /worker/package.json ./package.json COPY --from=build /worker/dist ./dist # GGUF weights download on first run into ./models (see llm-verdict.ts's # MODELS_DIRECTORY) — mounted as a named volume in docker-compose.yml so a # container restart doesn't re-download several hundred MB to a GB every # time. VOLUME ["/worker/models"] CMD ["node", "dist/index.js"]