1# apps/worker — headless BullMQ worker + domain-event stream consumers. 2# 3# WORKSPACE NOTE: this app is part of a pnpm monorepo (pnpm-workspace.yaml: 4# apps/*) and has a `workspace:*` dependency (@factory/shared) plus the shared 5# Prisma client from prisma/. A monorepo package cannot be built in isolation, 6# so build from the repository root with context at the root: 7# 8# docker build -f apps/worker/Dockerfile -t factory-worker . 9# 10# The image has no business HTTP surface — the only port it listens on is the 11# health server (TASK-0009 item 4): EXPOSE 4003 (/health + /health/ready). 12# It talks to Redis (BullMQ + factory:events streams), Postgres, OpenSearch, 13# S3, SMTP, ClamAV and the AI endpoint via environment (see .env.example). 14 15FROM node:20-alpine AS build 16WORKDIR /repo 17RUN corepack enable 18# Full monorepo source (a .dockerignore at the repo root should exclude 19# node_modules, dist, .git and app data so this stays lean). 20COPY . . 21RUN pnpm install --filter @factory/worker... \ 22 && pnpm --filter @factory/worker exec prisma generate \ 23 && pnpm --filter @factory/worker build 24 25FROM node:20-alpine AS runtime 26ENV NODE_ENV=production 27# Keep the monorepo layout so pnpm's relative node_modules symlinks resolve. 28WORKDIR /repo 29COPY --from=build /repo ./ 30 31WORKDIR /repo/apps/worker 32# Health server only (no business HTTP). Set WORKER_ID uniquely per replica. 33EXPOSE 4003 34CMD ["node", "dist/index.js"] 35