# Use Node.js 20 as the base image FROM node:20-alpine AS base # Install dependencies only when needed FROM base AS deps RUN apk add --no-cache libc6-compat WORKDIR /app # Install dependencies COPY package.json package-lock.json* ./ RUN npm ci # Build the application FROM base AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . # Set environment variables for build ENV NEXT_TELEMETRY_DISABLED 1 # Build Next.js application RUN npm run build # Production image FROM base AS runner WORKDIR /app ENV NODE_ENV production ENV NEXT_TELEMETRY_DISABLED 1 # Create a non-root user RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs # Copy built application COPY --from=builder /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static # Create data directory for file uploads (Hugging Face persistent storage) # Note: /data is persistent in Hugging Face Spaces RUN mkdir -p /data/documents /data/public /data/exams /data/files /data/sessions RUN chown -R nextjs:nodejs /data # Switch to non-root user USER nextjs # Expose port 7860 for Hugging Face Spaces EXPOSE 7860 # Set environment variables for Hugging Face Spaces ENV PORT=7860 ENV HOSTNAME="0.0.0.0" ENV REUBENOS_URL="http://0.0.0.0:7860" # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD node -e "require('http').get('http://localhost:7860/api/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1))" # Start both Next.js and MCP servers CMD ["sh", "-c", "node server.js"]