-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile.worker
More file actions
61 lines (58 loc) · 2.72 KB
/
Copy pathDockerfile.worker
File metadata and controls
61 lines (58 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# syntax=docker/dockerfile:1
# Clinical KB ingestion worker (Node pipeline + Python OCR stack).
# See docs/deployment-architecture.md for why the worker ships as a
# container instead of completing the edge-agent migration.
#
# Runtime contents (2026-07-13 audit, finding 12 — slimmed):
# - Node 24 + PRODUCTION-ONLY node_modules: the worker runs as a
# prebuilt esbuild bundle (dist/worker/index.mjs), so tsx and the rest
# of the dev toolchain never reach the image.
# - Tesseract OCR (Debian package, bundles English language data).
# - Python venv with worker/python/requirements.txt (PyMuPDF, Pillow,
# pytesseract). The venv's `python` matches the PYTHON_BIN default.
#
# Build: docker build -f Dockerfile.worker -t clinical-kb-worker .
# Run: docker run --env-file <secrets> clinical-kb-worker
# Secrets are injected at run time; nothing is baked into the image.
# Dev-inclusive install + bundle. scripts/build-worker.mjs resolves the
# `server-only` marker to the standalone stub at build time (the job
# run-tsx.mjs previously did at runtime) and keeps npm packages external,
# so the bundle resolves them from the runner's production node_modules.
FROM node:24-bookworm-slim AS build
WORKDIR /app
COPY package.json package-lock.json .npmrc ./
COPY scripts/check-node-engine.cjs scripts/check-node-engine.cjs
COPY scripts/install-git-hooks.mjs scripts/install-git-hooks.mjs
RUN npm ci
COPY . .
RUN node scripts/build-worker.mjs
# Production-only node_modules for the runtime stage. The preinstall/
# postinstall lifecycle scripts must be present in every npm-ci stage.
FROM node:24-bookworm-slim AS prod-deps
WORKDIR /app
COPY package.json package-lock.json .npmrc ./
COPY scripts/check-node-engine.cjs scripts/check-node-engine.cjs
COPY scripts/install-git-hooks.mjs scripts/install-git-hooks.mjs
RUN npm ci --omit=dev
FROM node:24-bookworm-slim AS runner
RUN apt-get update \
&& apt-get install -y --no-install-recommends python3 python3-venv tesseract-ocr \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY worker/python/requirements.txt worker/python/requirements.txt
RUN python3 -m venv /opt/ocr-venv \
&& /opt/ocr-venv/bin/pip install --no-cache-dir -r worker/python/requirements.txt
ENV PATH="/opt/ocr-venv/bin:${PATH}"
ENV NODE_ENV=production
COPY --from=prod-deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY worker/python worker/python
COPY package.json ./package.json
USER node
# Long-poll worker; WORKER_* env vars control claim batch size, concurrency,
# and the stale-claim window (see src/lib/env.ts).
#
# The bundle already has `server-only` stubbed (scripts/build-worker.mjs), so
# no runtime loader hook is needed. Guarded by
# tests/tsx-server-only-runner.test.ts.
CMD ["node", "dist/worker/index.mjs"]