# ---- Stage 1: Build ---- # Use the official Node.js 20 image as a base for building the app FROM node:20-slim AS builder # Set the working directory WORKDIR /app # Define build-time arguments - these will be automatically provided by Hugging Face ARG DATABASE_URL ARG DATABASE_NAME # Make these build-time args available as environment variables for the build command ENV DATABASE_URL=${DATABASE_URL:-"mongodb://dummy:dummy@localhost:27017/dummy"} ENV DATABASE_NAME=${DATABASE_NAME:-"dummy_db"} # The user for node images is 'node', so the default cache is /home/node/.cache ENV PUPPETEER_CACHE_DIR=/home/node/.cache/puppeteer # Copy package files. The --chown flag ensures the 'node' user owns these files. COPY --chown=node:node package.json ./ COPY --chown=node:node bun.lock ./ # CONSOLIDATED: Install ALL dependencies (prod and dev) needed for building. RUN npm install # EXPLICITLY INSTALL BROWSER: This is the most reliable method. # Puppeteer will download Chrome to the PUPPETEER_CACHE_DIR. RUN npx puppeteer browsers install chrome # Copy the rest of the application source code COPY --chown=node:node . . # BUILD: Build the Next.js app AND compile the worker script in one go. # Assumes you have a "build:worker": "npx tsc --project tsconfig.worker.json" script in package.json RUN npm run build && npm run build:worker # ---- Stage 2: Run ---- # Use a fresh Node.js 20 image for the final, lean container FROM node:20-slim # CRITICAL: Switch to root user temporarily to install system packages USER root # Install system dependencies from packages.txt for Puppeteer and PulseAudio COPY packages.txt . RUN apt-get update && \ cat packages.txt | tr -d '\r' | grep -v '^#' | grep -v '^[[:space:]]*$' | xargs -r apt-get install -y --no-install-recommends && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # CRITICAL: Switch back to the non-privileged 'node' user for security USER node WORKDIR /home/node/app # Set the runtime cache directory to a writable location # This must match the directory used in your start.sh script ENV PUPPETEER_CACHE_DIR=/tmp/puppeteer_cache # Copy only the necessary production artifacts from the builder stage COPY --chown=node:node --from=builder /app/.next ./.next COPY --chown=node:node --from=builder /app/public ./public # NOTE: We copy the whole node_modules from the builder. # An alternative is to copy only package.json and run "npm ci --only=production", # but this method is simpler and reliable for this use case. COPY --chown=node:node --from=builder /app/node_modules ./node_modules COPY --chown=node:node --from=builder /app/package.json ./package.json COPY --chown=node:node --from=builder /app/dist ./dist # ADDED: Copy the downloaded browser cache from the builder stage COPY --chown=node:node --from=builder /home/node/.cache/puppeteer /opt/puppeteer_cache ENV HOST=0.0.0.0 ENV PORT=7860 COPY --chown=node:node start.sh . RUN chmod +x ./start.sh EXPOSE 7860 CMD ["./start.sh"]