-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDockerfile
More file actions
118 lines (93 loc) · 5.47 KB
/
Copy pathDockerfile
File metadata and controls
118 lines (93 loc) · 5.47 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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# Build stage
# Expects build context: repository root (.), so shared and apps/temporal are available.
FROM node:24-bookworm-slim AS builder
WORKDIR /app
# Copy package files and config from apps/temporal
COPY apps/temporal/package.json ./
COPY apps/temporal/tsconfig.json ./
COPY apps/temporal/prisma.config.ts ./
# Copy shared prisma schema and prisma.config (tsconfig references ../shared/prisma.config.ts)
COPY apps/shared/prisma ./shared/prisma
COPY apps/shared/prisma.config.ts /shared/prisma.config.ts
# Copy workspace packages referenced as file: dependencies (file:../../packages/* resolves to /packages/*)
COPY packages/logging /packages/logging
RUN cd /packages/logging && npm install --ignore-scripts && npm run build
COPY packages/graph-insertion-slots /packages/graph-insertion-slots
RUN cd /packages/graph-insertion-slots && npm install && npm run build
COPY packages/blob-storage-paths /packages/blob-storage-paths
RUN cd /packages/blob-storage-paths && npm install --ignore-scripts && npm run build
COPY packages/graph-workflow /packages/graph-workflow
RUN cd /packages/graph-workflow && npm install --ignore-scripts && npm run build
COPY packages/temporal-payload-codec /packages/temporal-payload-codec
RUN cd /packages/temporal-payload-codec && npm install --ignore-scripts && npm run build
COPY packages/monitoring /packages/monitoring
# @ai-di/shared-logging is a peerDependency of monitoring (not needed at build time).
# Link the already-built logging package so npm doesn't fetch it from the registry.
RUN mkdir -p /packages/monitoring/node_modules/@ai-di && \
ln -s /packages/logging /packages/monitoring/node_modules/@ai-di/shared-logging && \
cd /packages/monitoring && npm install --ignore-scripts && npm run build
# Install dependencies (no lockfile — monorepo file: paths don't match Docker layout)
RUN npm install --ignore-scripts
# Generate Prisma client: patch schema to set output; url comes from prisma.config via DATABASE_URL.
# The shared generate-prisma.js expects monorepo layout; we use a direct generate.
RUN node -e "\
const fs = require('fs'); \
const p = './shared/prisma/schema.prisma'; \
let s = fs.readFileSync(p, 'utf8'); \
s = s.replace(/generator client \\{[^}]*\\}/s, 'generator client {\\n provider = \"prisma-client-js\"\\n output = \"../../src/generated\"\\n}'); \
fs.writeFileSync(p, s); \
"
# DATABASE_URL required for Prisma config load at generate; placeholder is fine (no connection during build)
ARG DATABASE_URL=postgresql://localhost:5432/dummy
ENV DATABASE_URL=${DATABASE_URL}
RUN npx prisma generate --schema=./shared/prisma/schema.prisma
# Copy source and build. Use a build tsconfig that only includes src (exclude prisma.config).
# The parent tsconfig's `paths.mupdf` is `../../node_modules/...` (correct for the monorepo
# layout); in this container `node_modules` sits next to the tsconfig, so we re-declare
# `paths` here to point at the in-container location. `paths` in an extending config
# replaces — not merges with — the parent's, so `@generated/*` must be repeated.
COPY apps/temporal/src ./src
RUN echo '{"extends":"./tsconfig.json","compilerOptions":{"rootDir":"./src","baseUrl":".","paths":{"@generated/*":["src/generated/*"],"mupdf":["./node_modules/mupdf/dist/mupdf"]}},"include":["src/**/*.ts"]}' > tsconfig.build.json && \
npx tsc -p tsconfig.build.json
# Production stage
FROM node:24-bookworm-slim AS production
WORKDIR /app
# Create non-root user (align with backend)
RUN groupadd -g 1001 nodejs && \
useradd -m -u 1001 -g 1001 nodeuser
# npm cache for OpenShift
RUN mkdir -p /.npm && \
chgrp -R 0 /.npm && \
chmod -R g=u /.npm
# Copy pre-built workspace packages from builder (avoids needing tsc in production stage)
COPY --from=builder /packages/logging /packages/logging
COPY --from=builder /packages/graph-insertion-slots /packages/graph-insertion-slots
COPY --from=builder /packages/blob-storage-paths /packages/blob-storage-paths
COPY --from=builder /packages/graph-workflow /packages/graph-workflow
COPY --from=builder /packages/temporal-payload-codec /packages/temporal-payload-codec
COPY --from=builder /packages/monitoring /packages/monitoring
# Package files and production deps
COPY apps/temporal/package.json ./
# --ignore-scripts is safe here because all native binaries (prisma, esbuild, etc.)
# were already built in the builder stage and are copied over. No postinstall
# scripts need to run again in production.
RUN npm install --omit=dev --ignore-scripts && \
npm cache clean --force
# Built output and generated Prisma client from builder
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/src/generated ./src/generated
# Node resolves require('@generated/client') from node_modules; tsconfig paths are compile-time only.
RUN mkdir -p node_modules/@generated && cp -r src/generated node_modules/@generated/client
# Prisma schema for any runtime resolve
COPY --from=builder /app/shared/prisma ./shared/prisma
# Tesseract OSD trained data for the document.normalizeOrientation activity.
# tesseract.js's first lookup is `fs.readFile(${cachePath||'.'}/osd.traineddata)`,
# which resolves to ${process.cwd()}/osd.traineddata. The worker is started as
# `node dist/worker.js` with WORKDIR=/app, so the file must sit at /app/osd.traineddata.
# Without this COPY, tesseract.js silently falls back to fetching from the
# jsdelivr CDN on every cold container start.
COPY apps/temporal/osd.traineddata ./osd.traineddata
RUN chown -R nodeuser:nodejs /app
USER nodeuser
ENV NODE_ENV=production
CMD ["node", "dist/worker.js"]