# syntax=docker/dockerfile:1.7 # # PayloadCMS production image. Built and run by docker-compose. # # We use Next.js `output: 'standalone'` so the runtime stage doesn't have # to ship the entire node_modules tree — Next analyses the code, picks # only the files that are actually required at runtime, and bundles them # under .next/standalone/. This sidesteps the pnpm content-addressable # store / bin-link issues we hit with the workspace install. # # We install pnpm via `npm install -g pnpm@9` instead of corepack so # the version negotiation is unambiguous across Node 20 minor releases. FROM node:20-alpine AS base RUN npm install -g pnpm@9 WORKDIR /repo # ---- deps ----------------------------------------------------------------- # Install ALL workspace deps at the root so apps/cms can resolve its # siblings (@payloadcms/*, next, react, etc.). FROM base AS deps COPY pnpm-workspace.yaml package.json ./ COPY apps/cms/package.json ./apps/cms/package.json COPY apps/web/package.json ./apps/web/package.json COPY pnpm-lock.yaml* ./ RUN if [ -f pnpm-lock.yaml ]; then \ pnpm install --frozen-lockfile; \ else \ echo "No pnpm-lock.yaml found; running pnpm install (generates one)"; \ pnpm install; \ fi # ---- build ---------------------------------------------------------------- FROM deps AS build COPY apps/cms ./apps/cms WORKDIR /repo/apps/cms RUN pnpm run build # Some apps don't ship a `public/` dir; ensure one exists so the # runtime COPY below doesn't fail. RUN mkdir -p /repo/apps/cms/public # ---- runtime -------------------------------------------------------------- # Compose the self-contained runtime image from the standalone output. # - .next/standalone/ contains the server.js entrypoint and a trimmed # node_modules tree with only the files Next determined are needed. # - .next/static/ is the hashed client-side bundles; standalone # does NOT include it, so we copy it over manually. # - public/ static assets served from the web root (may be # absent; the COPY is guarded). FROM node:20-alpine AS runtime ENV NODE_ENV=production ENV PORT=3000 ENV HOSTNAME=0.0.0.0 WORKDIR /repo/apps/cms COPY --from=build /repo/apps/cms/.next/standalone ./ COPY --from=build /repo/apps/cms/.next/static ./.next/static COPY --from=build /repo/apps/cms/public ./public EXPOSE 3000 CMD ["node", "server.js"]