# ===== Stage 1: Build ===== FROM node:20-bookworm AS builder WORKDIR /app # Install dependencies (need all deps for tsc + vite build) COPY package.json package-lock.json ./ RUN npm ci # Copy source and build frontend COPY . . RUN npm run build # ===== Stage 2: Production ===== FROM node:20-bookworm-slim # Install: CJK fonts (PDF), build tools (better-sqlite3 native addon) RUN apt-get update && \ apt-get install -y --no-install-recommends \ fonts-noto-cjk \ python3 \ make \ g++ \ && rm -rf /var/lib/apt/lists/* WORKDIR /app # Install production deps + tsx (needed to run TypeScript server at runtime) COPY package.json package-lock.json ./ RUN npm ci --omit=dev && npm install tsx # Copy built frontend COPY --from=builder /app/dist ./dist # Copy server source (runs via tsx, no compile step) COPY server ./server # Data directory for SQLite (mount as volume for persistence) RUN mkdir -p /app/data VOLUME /app/data # Default port ENV PORT=3001 EXPOSE 3001 # Health check HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD node -e "fetch('http://localhost:3001/api/health').then(r=>r.ok?process.exit(0):process.exit(1)).catch(()=>process.exit(1))" CMD ["npx", "tsx", "server/index.ts"]