mmy / Dockerfile
Mohammad Shahid
.
aa68f1b
# ---- 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"]