# syntax=docker/dockerfile:1 # # Next.js Dockerfile for passenger web (portal + backoffice). # Builds with turbo, runs with Node.js standalone output. # # Build example (portal): # DOCKER_BUILDKIT=1 docker build \ # --build-arg APP_PACKAGE=@edr/passenger-portal \ # --build-arg APP_PATH=apps/edr-passenger-web/portal \ # --build-arg PORT=5174 \ # -f infrastructure/docker/Dockerfile.passenger-web . # ARG APP_PACKAGE=@edr/passenger-portal ARG APP_PATH=apps/edr-passenger-web/portal ARG PORT=5174 ARG NEXT_PUBLIC_API_URL FROM node:24.15.0-alpine AS base RUN apk add --no-cache libc6-compat ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" RUN corepack enable WORKDIR /app FROM base AS pruner ARG APP_PACKAGE COPY . . RUN pnpm dlx turbo prune "${APP_PACKAGE}" --docker FROM base AS installer COPY --from=pruner /app/out/json/ . COPY --from=pruner /app/out/pnpm-lock.yaml ./pnpm-lock.yaml RUN --mount=type=secret,id=npmrc,target=./.npmrc,required=false \ --mount=type=cache,id=pnpm,target=/pnpm/store \ pnpm install --frozen-lockfile FROM base AS builder ARG APP_PACKAGE ARG APP_PATH ARG NEXT_PUBLIC_API_URL ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} RUN if [ -z "$NEXT_PUBLIC_API_URL" ]; then \ echo "ERROR: NEXT_PUBLIC_API_URL must be set" && \ exit 1; \ fi COPY --from=installer /app/ . COPY --from=pruner /app/out/full/ . RUN pnpm turbo build --filter="${APP_PACKAGE}..." # Runner: copy the standalone output produced by Next.js. # With output:'standalone' in a pnpm monorepo, Next.js emits: # .next/standalone/ <- shared workspace node_modules # .next/standalone// <- app server.js + app-level node_modules # .next/static/ <- hashed client assets # public/ <- static public files # We copy the full standalone tree to /app, then WORKDIR into the app # subdirectory so `node server.js` resolves correctly. FROM node:24.15.0-alpine AS runner ARG APP_PATH ARG PORT=5174 ENV PORT=${PORT} ENV NODE_ENV=production WORKDIR /app RUN addgroup --system --gid 1001 nodejs \ && adduser --system --uid 1001 --ingroup nodejs nextjs # Copy the entire standalone tree (includes root node_modules symlinks) COPY --from=builder --chown=nextjs:nodejs /app/${APP_PATH}/.next/standalone ./ # Overlay the hashed static assets and public files at the path Next.js expects COPY --from=builder --chown=nextjs:nodejs /app/${APP_PATH}/.next/static ./${APP_PATH}/.next/static COPY --from=builder --chown=nextjs:nodejs /app/${APP_PATH}/public ./${APP_PATH}/public USER nextjs # server.js lives at /server.js inside the standalone tree WORKDIR /app/${APP_PATH} EXPOSE ${PORT} CMD ["node", "server.js"]