# ── Stage 1: Build frontend ────────────────────────────────────────────────── FROM node:20-alpine AS builder WORKDIR /app # Install build tools needed for native modules and frontend build RUN apk add --no-cache python3 build-base sqlite-dev COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build # ── Stage 2: Production image ─────────────────────────────────────────────── FROM node:20-alpine # Allow forcing build from source (useful when prebuilt binaries are not available) ARG BUILD_FROM_SOURCE=false ENV npm_config_build_from_source=${BUILD_FROM_SOURCE} # Install build tools and sqlite dev headers for compiling native modules RUN apk add --no-cache python3 build-base sqlite-dev WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci --omit=dev && npm cache clean --force # Remove build tools after install to keep image smaller RUN apk del build-base python3 # Copy server code COPY server/ ./server/ # Copy built frontend from builder stage COPY --from=builder /app/dist ./dist # Create uploads directory RUN mkdir -p uploads/avatars uploads/branding ENV NODE_ENV=production ENV PORT=3001 ENV SQLITE_PATH=/app/data/redlight.db EXPOSE 3001 # Data volumes for persistent storage VOLUME ["/app/uploads", "/app/data"] CMD ["node", "server/index.js"]