Next.js Curriculum
HardProduction Operations100% Free35 min read

Docker Containerization with output: "standalone"

The 30-Second Interview Answer

Next.js provides the output: "standalone" configuration option, which automatically traces and packages only the production dependencies needed by your application. This shrinks Docker container image sizes from over 1.5GB down to ~120MB, eliminating node_modules bloat and enabling secure, multi-stage, rootless Docker deployments on AWS ECS, Kubernetes, or GCP Cloud Run.

Learning Objectives

Configure output: "standalone" in next.config.js for self-hosted containerization.

Construct a secure, multi-stage Dockerfile (deps, builder, runner).

Copy static assets and public directories correctly into the standalone server tree.

Run the production container as a non-root user for enterprise security compliance.

Prerequisites & Background Knowledge
Docker multi-stage buildsContainer security best practicesNode.js production runtime

Why Interviewers Care

Crucial for enterprise roles where Next.js applications are self-hosted in Kubernetes or enterprise cloud clusters rather than Vercel.

The Challenge

How does output: "standalone" work in Next.js? Write a production-ready, multi-stage Dockerfile that minimizes image size and runs as an unprivileged user.

Code Architecture & Implementation

1# Stage 1: Dependencies cache
2FROM node:20-alpine AS deps
3RUN apk add --no-cache libc6-compat
4WORKDIR /app
5COPY package.json package-lock.json ./
6RUN npm ci
7
8# Stage 2: Build the Next.js application
9FROM node:20-alpine AS builder
10WORKDIR /app
11COPY --from=deps /app/node_modules ./node_modules
12COPY . .
13# Disable Next.js telemetry during build
14ENV NEXT_TELEMETRY_DISABLED=1
15RUN npm run build
16
17# Stage 3: Production Runner (Ultra-small standalone image)
18FROM node:20-alpine AS runner
19WORKDIR /app
20ENV NODE_ENV=production
21ENV NEXT_TELEMETRY_DISABLED=1
22
23# Create unprivileged system user for security compliance
24RUN addgroup --system --gid 1001 nodejs && \
25 adduser --system --uid 1001 nextjs
26
27# Copy static assets and traced standalone server
28COPY --from=builder /app/public ./public
29COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
30COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
31
32USER nextjs
33EXPOSE 3000
34ENV PORT=3000
35ENV HOSTNAME="0.0.0.0"
36
37# Run the standalone Node server directly without npm!
38CMD ["node", "server.js"]

Architectural Explanation

Standard npm install packages hundreds of devDependencies (TypeScript, ESLint, Tailwind compilers) that are useless at runtime. With output: "standalone", Next.js analyzes the AST of your built application and copies ONLY the exact files and node_modules packages actually executed at runtime into .next/standalone. The resulting server.js file can run standalone with a raw node server.js command, slashing memory footprint, deployment time, and security attack surface.

Common Mistakes & Anti-Patterns

Forgetting to copy `.next/static` into `.next/standalone/.next/static`, causing all CSS and client JavaScript bundles to return 404 in production.

Running containers as root user (`UID 0`), violating enterprise container security standards.

Copying the entire source `node_modules` directory into the final production image.

Interview Follow-Up Traps

The interviewer asks: "Why do client images break when I run the standalone Docker container?" Because static assets (`public/` and `.next/static/`) must be explicitly copied into the runner stage, or hosted separately on a CDN like S3/CloudFront.

Frequently Asked Questions

Does standalone output support image optimization?

Yes, but ensure `sharp` is installed in dependencies so the Alpine container can perform high-speed image compression.

Add a Docker `HEALTHCHECK CMD wget --spider http://localhost:3000/api/health || exit 1`.

Yes! It is the industry standard for deploying Next.js on AWS EKS, GCP GKE, and self-hosted Kubernetes.