# ───────────────────────────────────────────────────────────────────────────── # Stage 1: Builder # Installs ALL dependencies and compiles the React frontend inside Docker. # Nothing needs to be installed on the host machine except Docker itself. # ───────────────────────────────────────────────────────────────────────────── FROM node:20-alpine AS builder WORKDIR /build # Install backend deps COPY package.json ./ RUN npm install # Install frontend deps and build React app COPY client/package.json ./client/ RUN cd client && npm install COPY client/ ./client/ RUN cd client && npm run build # ───────────────────────────────────────────────────────────────────────────── # Stage 2: Production image # ───────────────────────────────────────────────────────────────────────────── FROM node:20-alpine AS production # Chromium for Puppeteer PDF generation RUN apk add --no-cache \ chromium \ nss \ freetype \ harfbuzz \ ca-certificates \ ttf-freefont ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser ENV NODE_ENV=production ENV PORT=3001 ENV DB_PATH=/data/cpas.db WORKDIR /app # Copy backend node_modules and compiled frontend from builder COPY --from=builder /build/node_modules ./node_modules COPY --from=builder /build/client/dist ./client/dist # Copy all backend source files COPY server.js ./ COPY package.json ./ COPY db/ ./db/ COPY pdf/ ./pdf/ # Ensure data directory exists RUN mkdir -p /data EXPOSE 3001 HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD wget -qO- http://localhost:3001/api/health || exit 1 CMD ["node", "server.js"]