# Multi-stage Dockerfile for Next.js with Prisma FROM node:20-alpine AS base # Install pnpm ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" RUN corepack enable # Install dependencies only when needed FROM base AS deps # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. RUN apk add --no-cache libc6-compat WORKDIR /app # Install dependencies based on the preferred package manager COPY package.json pnpm-lock.yaml* ./ RUN \ if [ -f pnpm-lock.yaml ]; then pnpm install --frozen-lockfile; \ else echo "Lockfile not found." && exit 1; \ fi # Rebuild the source code only when needed FROM base AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . # Set a dummy DATABASE_URL for build time (Prisma needs it to generate client) ENV DATABASE_URL="file:/tmp/build.db" # Generate Prisma client RUN pnpm prisma generate # Initialize the database schema for build time RUN pnpm prisma migrate deploy || pnpm prisma db push # Build the application RUN pnpm run build # Production image, copy all the files and run next FROM base AS runner # Set timezone to Europe/Paris and install sqlite3 for backups RUN apk add --no-cache tzdata sqlite RUN ln -snf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo Europe/Paris > /etc/timezone WORKDIR /app ENV NODE_ENV=production # Uncomment the following line in case you want to disable telemetry during runtime. # ENV NEXT_TELEMETRY_DISABLED 1 RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs # Copy the public folder COPY --from=builder /app/public ./public # Set the correct permission for prerender cache RUN mkdir .next RUN chown nextjs:nodejs .next # Automatically leverage output traces to reduce image size # https://nextjs.org/docs/advanced-features/output-file-tracing COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static # Copy Prisma schema COPY --from=builder /app/prisma ./prisma # Copy scripts (including init-db.js) COPY --from=builder /app/scripts ./scripts # Copy pnpm node_modules (includes .pnpm store with Prisma client) COPY --from=builder /app/node_modules ./node_modules # Create data directory for SQLite and backups RUN mkdir -p /app/data/backups && chown -R nextjs:nodejs /app/data # Set all ENV vars before switching user ENV PORT=3000 ENV HOSTNAME="0.0.0.0" ENV TZ=Europe/Paris USER nextjs EXPOSE 3000 # Start the application with smart database initialization CMD ["sh", "-c", "node scripts/init-db.js && node server.js"]