# ======================================================== # Stage 1: Build the React + Vite frontend and Express server # ======================================================== FROM node:22-alpine AS builder WORKDIR /app # Install dependencies first (layer caching) COPY package.json bun.lock ./ RUN npm install -g bun RUN bun install # Copy application source code COPY . . # Optional Build Argument for Google Maps API Key ARG VITE_GOOGLE_MAPS_API_KEY="" ENV VITE_GOOGLE_MAPS_API_KEY=$VITE_GOOGLE_MAPS_API_KEY # Build production bundle (Vite client + server.cjs) RUN npm run build # ======================================================== # Stage 2: Serve full-stack application (API + SPA) with Node.js # ======================================================== FROM node:22-alpine AS runner WORKDIR /app ENV NODE_ENV=production ENV PORT=3000 # Install production dependencies only COPY package.json bun.lock ./ RUN npm install -g bun RUN bun install --production # Copy built bundle from builder stage COPY --from=builder /app/dist ./dist # Create persistent database directory RUN mkdir -p /app/data VOLUME ["/app/data"] # Expose HTTP application port EXPOSE 3000 # Container healthcheck HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD wget --quiet --tries=1 --spider http://localhost:3000/healthz || exit 1 # Start production full-stack server CMD ["node", "dist/server.cjs"]