Nextjs docker standalone build
Skill kjuhwa/skills-hub/skills/devops/nextjs-docker-standalone-build
Three-stage Docker build for a Next.js app with pnpm workspaces — deps / builder / runner stages, standalone output for a minimal production image.From its SKILL.md
npx -y skills add kjuhwa/skills-hub --skill nextjs-docker-standalone-buildAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
3.4 KB, 788 tokens by cl100k_base, as published. Nobody here has run it
When to use
- Deploying a Next.js app that lives inside a pnpm workspace with shared packages.
- You want the production image to contain only the traced node_modules, not the full monorepo.
- You need a deterministic reproducible build with
pnpm install --frozen-lockfile.
Steps
- Deps stage — resolve dependencies from the full workspace but without copying source. This gets cached unless package.jsons change:
FROM node:22-alpine AS deps RUN corepack enable && corepack prepare [email protected] --activate WORKDIR /app COPY pnpm-lock.yaml pnpm-workspace.yaml package.json turbo.json .npmrc ./ COPY apps/web/package.json apps/web/ COPY packages/core/package.json packages/core/ COPY packages/ui/package.json packages/ui/ COPY packages/views/package.json packages/views/ COPY packages/tsconfig/package.json packages/tsconfig/ RUN pnpm install --frozen-lockfile - Builder stage — overlay the source, re-link pnpm symlinks, build:
The second install withFROM node:22-alpine AS builder RUN corepack enable && corepack prepare [email protected] --activate WORKDIR /app COPY --from=deps /app ./ COPY package.json turbo.json pnpm-workspace.yaml ./ COPY apps/web/ apps/web/ COPY packages/ packages/ RUN pnpm install --frozen-lockfile --offline ARG REMOTE_API_URL=http://backend:8080 ENV REMOTE_API_URL=$REMOTE_API_URL ENV STANDALONE=true RUN pnpm --filter @org/web build--offlinere-creates symlinks the COPY overwrote. - In
apps/web/next.config.ts, enable standalone output:export default { output: process.env.STANDALONE ? "standalone" : undefined, transpilePackages: ["@org/core", "@org/ui", "@org/views"], }; - Runner stage — copy only the standalone output + static + public:
FROM node:22-alpine AS runner WORKDIR /app ENV NODE_ENV=production RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextjs COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static COPY --from=builder --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public USER nextjs EXPOSE 3000 ENV PORT=3000 HOSTNAME=0.0.0.0 CMD ["node", "apps/web/server.js"]
Example
Image size: ~150-250 MB runner vs 1 GB+ for "copy the whole repo and run pnpm start". Build time: first ~3 min, subsequent ~45 s once deps stage caches.
Caveats
- If you add or remove a shared package, update the deps-stage
COPYlist. - Standalone output traces only what's imported from the app entrypoint — dynamic
require()or runtime-loaded files may be missing and need explicitoutputFileTracingIncludesconfig. - The re-install in the builder is
--offline; it fails if deps aren't already in the pnpm store from the deps stage.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.