# ================================================== # MULTI-STAGE DOCKERFILE - WORKERS (PDF, Exercise, Notification) # Node.js 20 LTS + TypeScript + Real Health Checks # ================================================== # -------------------------------------------------- # STAGE 1: Base Dependencies # -------------------------------------------------- FROM node:20-alpine AS base WORKDIR /app # Install build dependencies RUN apk add --no-cache \ python3 \ make \ g++ \ postgresql-client \ poppler-utils \ imagemagick \ curl \ openssl \ openssl-dev \ libc6-compat # Copy package files COPY backend/package*.json ./ COPY backend/prisma ./prisma/ # Install all dependencies RUN npm ci && \ npm cache clean --force # -------------------------------------------------- # STAGE 2: Builder # -------------------------------------------------- FROM node:20-alpine AS builder WORKDIR /app # Copy dependencies from base COPY --from=base /app/node_modules ./node_modules COPY backend/package*.json ./ COPY backend/tsconfig.json ./ COPY backend/src ./src COPY backend/prisma ./prisma # Build TypeScript RUN npm run build # -------------------------------------------------- # STAGE 3: PDF Worker # -------------------------------------------------- FROM node:20-alpine AS pdf-worker WORKDIR /app # Install runtime dependencies for PDF processing RUN apk add --no-cache \ postgresql-client \ poppler-utils \ imagemagick \ curl \ wget \ openssl \ libc6-compat # Create non-root user RUN addgroup -g 1001 -S worker && \ adduser -S worker -u 1001 # Copy built application and dependencies COPY --from=base --chown=worker:worker /app/node_modules ./node_modules COPY --from=builder --chown=worker:worker /app/dist ./dist COPY --from=builder --chown=worker:worker /app/prisma ./prisma COPY --from=base --chown=worker:worker /app/package*.json ./ # Create directories RUN mkdir -p /app/pdfs /app/pdfs/processed /app/logs && \ chown -R worker:worker /app # Switch to non-root user USER worker # Set worker type ENV WORKER_TYPE=pdf ENV NODE_ENV=production ENV HEALTH_PORT=3002 # Expose health check port EXPOSE 3002 # Health check - Real HTTP endpoint check HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ CMD wget --quiet --tries=1 --spider http://localhost:3002/health || exit 1 # Start PDF worker CMD ["node", "dist/workers/runner.js"] # -------------------------------------------------- # STAGE 4: Exercise Worker (AI) # -------------------------------------------------- FROM node:20-alpine AS exercise-worker WORKDIR /app # Install runtime dependencies RUN apk add --no-cache \ postgresql-client \ curl \ wget \ openssl \ libc6-compat # Create non-root user RUN addgroup -g 1001 -S worker && \ adduser -S worker -u 1001 # Copy built application and dependencies COPY --from=base --chown=worker:worker /app/node_modules ./node_modules COPY --from=builder --chown=worker:worker /app/dist ./dist COPY --from=builder --chown=worker:worker /app/prisma ./prisma COPY --from=base --chown=worker:worker /app/package*.json ./ # Create directories RUN mkdir -p /app/logs && \ chown -R worker:worker /app # Switch to non-root user USER worker # Set worker type ENV WORKER_TYPE=exercise ENV NODE_ENV=production ENV HEALTH_PORT=3003 # Expose health check port EXPOSE 3003 # Health check - Real HTTP endpoint check HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ CMD wget --quiet --tries=1 --spider http://localhost:3003/health || exit 1 # Start exercise worker CMD ["node", "dist/workers/runner.js"] # -------------------------------------------------- # STAGE 5: Notification Worker (Telegram) # -------------------------------------------------- FROM node:20-alpine AS notification-worker WORKDIR /app # Install runtime dependencies RUN apk add --no-cache \ postgresql-client \ curl \ wget \ openssl \ libc6-compat # Create non-root user RUN addgroup -g 1001 -S worker && \ adduser -S worker -u 1001 # Copy built application and dependencies COPY --from=base --chown=worker:worker /app/node_modules ./node_modules COPY --from=builder --chown=worker:worker /app/dist ./dist COPY --from=builder --chown=worker:worker /app/prisma ./prisma COPY --from=base --chown=worker:worker /app/package*.json ./ # Create directories RUN mkdir -p /app/logs && \ chown -R worker:worker /app # Switch to non-root user USER worker # Set worker type ENV WORKER_TYPE=notification ENV NODE_ENV=production ENV HEALTH_PORT=3004 # Expose health check port EXPOSE 3004 # Health check - Real HTTP endpoint check HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ CMD wget --quiet --tries=1 --spider http://localhost:3004/health || exit 1 # Start notification worker CMD ["node", "dist/workers/runner.js"] # -------------------------------------------------- # METADATA # -------------------------------------------------- LABEL maintainer="math-platform-builders" LABEL description="Math Platform Workers (PDF, Exercise, Notification) - Production Ready" LABEL version="1.0.0"