# syntax=docker/dockerfile:1.7 # ---- base ---- FROM node:24.12.0-slim AS base WORKDIR /app # Pin Yarn classic (v1) exactly RUN corepack enable \ && corepack prepare yarn@1.22.22 --activate ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 # ---- deps ---- FROM base AS deps # If you ever add native deps, you may need build tools. # Kept minimal for faster builds. COPY package.json yarn.lock ./ # Leverage BuildKit cache for Yarn (optional but nice when enabled) RUN --mount=type=cache,target=/usr/local/share/.cache/yarn \ yarn install --frozen-lockfile # ---- builder ---- FROM base AS builder ENV NODE_ENV=production COPY --from=deps /app/node_modules ./node_modules COPY . . RUN yarn build # ---- runner (prod) ---- FROM node:24.12.0-slim AS runner WORKDIR /app RUN corepack enable \ && corepack prepare yarn@1.22.22 --activate ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 # Use the built-in non-root user that comes with the official Node image USER node # Only copy what we need at runtime COPY --chown=node:node package.json yarn.lock ./ COPY --chown=node:node --from=deps /app/node_modules ./node_modules COPY --chown=node:node --from=builder /app/public ./public COPY --chown=node:node --from=builder /app/.next ./.next EXPOSE 3000 CMD ["yarn", "start"] # ---- dev ---- FROM base AS dev ENV NODE_ENV=development COPY package.json yarn.lock ./ RUN --mount=type=cache,target=/usr/local/share/.cache/yarn \ yarn install --frozen-lockfile # In dev we'll mount the whole repo as a volume. Still copy for image completeness. COPY . . EXPOSE 3000 CMD ["yarn", "dev", "-H", "0.0.0.0", "-p", "3000"]