/ blog/dockerizing-nextjs-production
blog / dockerizing-nextjs-production / overview.md

Dockerizing Next.js for Standalone Production Deployments

Vercel is great, but sometimes you need to host Next.js on your own Kubernetes cluster or VPS. Here's the optimal multi-stage Dockerfile for Next.js App Router.

The Problem with Next.js Dockerfiles

A naive npm run build && npm start inside a Docker container results in a 1.5GB+ image. It includes all your devDependencies, the entire uncompressed node_modules folder, and unnecessary source files.

Next.js has a built-in feature called Standalone Output that fixes this.

Enabling Standalone Mode

In your next.config.js:

module.exports = {
  output: 'standalone',
}

This tells Next.js to trace your application dependencies and output only the files strictly necessary to run the production server into a .next/standalone folder.

The Multi-Stage Dockerfile

FROM node:18-alpine AS base

# 1. Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

# 2. Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# 3. Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production

# Don't run as root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
# Automatically leverage output traces to reduce image size
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
ENV PORT 3000

CMD ["node", "server.js"]

This yields a production image that is usually under 150MB, boots instantly, and contains zero dev dependencies.

Tags

devopsnextjsdocker
0
0