FROM node:26-alpine AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci FROM node:26-alpine AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . # NEXT_PUBLIC_* values are inlined at build time, and pages are prerendered # with data from Sanity during the build ARG NEXT_PUBLIC_SANITY_PROJECT_ID ARG NEXT_PUBLIC_SANITY_DATASET ARG NEXT_PUBLIC_UMAMI_SRC ARG NEXT_PUBLIC_UMAMI_WEBSITE_ID RUN npm run build # Only the standalone server and its traced dependencies end up in the final # image, not the full node_modules or the source FROM node:26-alpine AS runner WORKDIR /app ENV NODE_ENV=production ENV PORT=9000 ENV HOSTNAME=0.0.0.0 # The server writes regenerated pages to .next, so the files must be owned by # the user it runs as COPY --from=builder --chown=node:node /app/.next/standalone ./ COPY --from=builder --chown=node:node /app/.next/static ./.next/static COPY --from=builder --chown=node:node /app/public ./public USER node EXPOSE 9000 CMD ["node", "server.js"]