# Adapted from novelpad-desktop Dockerfile @ 62c56b87 — same multi-stage # shape (base → deps → builder → prod-deps → runner), trimmed to this repo: # no native modules (pg/pdfjs/fast-xml-parser are pure JS), so no # python3/make/g++ layer; no pm2 (one process per container, compose picks # the command); default CMD is the DBOS worker, the review app overrides. # Stage 1: Base image with yarn + turbo FROM node:22-slim AS base WORKDIR /app RUN corepack enable && corepack prepare yarn@4.5.0 && npm i -g turbo # Stage 2: Install dependencies (rebuilds only when manifests change) FROM base AS deps WORKDIR /app COPY package.json yarn.lock .yarnrc.yml ./ COPY packages/config/package.json packages/config/ COPY packages/outreach-core/package.json packages/outreach-core/ COPY packages/outreach-ai/package.json packages/outreach-ai/ COPY apps/outreach-worker/package.json apps/outreach-worker/ COPY apps/outreach-review/package.json apps/outreach-review/ RUN --mount=type=cache,target=/root/.yarn/berry/cache \ yarn install --immutable # Stage 3: Build everything FROM base AS builder WORKDIR /app COPY --from=deps /app ./ COPY . . RUN --mount=type=cache,target=/app/.turbo \ turbo build --filter=@novelpad/outreach-worker... --filter=@novelpad/outreach-review... # Stage 4: Production dependencies only FROM deps AS prod-deps RUN yarn workspaces focus --production @novelpad/outreach-worker @novelpad/outreach-review && yarn cache clean # Stage 5: Final production image (no build tools) FROM node:22-slim AS runner WORKDIR /app ENV NODE_ENV=production RUN corepack enable && corepack prepare yarn@4.5.0 COPY --from=prod-deps --chown=node:node /app/node_modules ./node_modules COPY --from=prod-deps --chown=node:node /app/package.json ./package.json COPY --from=prod-deps --chown=node:node /app/yarn.lock ./yarn.lock COPY --from=prod-deps --chown=node:node /app/.yarnrc.yml ./.yarnrc.yml COPY --chown=node:node packages/config/package.json packages/config/ COPY --chown=node:node packages/outreach-core/package.json packages/outreach-core/ COPY --chown=node:node packages/outreach-ai/package.json packages/outreach-ai/ COPY --chown=node:node apps/outreach-worker/package.json apps/outreach-worker/ COPY --chown=node:node apps/outreach-review/package.json apps/outreach-review/ COPY --from=builder --chown=node:node /app/packages/outreach-core/dist ./packages/outreach-core/dist COPY --from=builder --chown=node:node /app/packages/outreach-core/drizzle ./packages/outreach-core/drizzle COPY --from=builder --chown=node:node /app/packages/outreach-ai/dist ./packages/outreach-ai/dist COPY --from=builder --chown=node:node /app/apps/outreach-worker/build ./apps/outreach-worker/build COPY --from=builder --chown=node:node /app/apps/outreach-review/build ./apps/outreach-review/build USER node CMD ["node", "apps/outreach-worker/build/main.js"]