Spaces:
Paused
Paused
| # ---- 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"] |