
How I Reduced My Next.js Docker Image from 4.1 GB to 230 MB
As developers, we’re constantly looking for ways to make our applications faster, smaller, and easier to deploy. Recently, I discovered just how much bloat was hiding in my Docker image—and how simple it was to eliminate it with a few smart changes.
📦 The Starting Point
I’m working on a full-stack Next.js project, containerized for deployment. My original Docker image, built using npm and a fairly typical Dockerfile, weighed in at a whopping 4.1 GB.
That’s fine during development, but once you’re pushing and pulling this image in CI/CD, across environments, or to a production registry—it quickly becomes a bottleneck.
⚡️ Step 1: Switching from npm to pnpm
The first change I made was switching from npm to pnpm. It uses a global content-addressable store and symlinks, meaning:
No duplicated dependencies
Smaller node_modules
Faster install times
Commands used:
npm install -g pnpm
rm -rf node_modules package-lock.json
pnpm install
This change alone reduced the image size from 4.1 GB to 1.6 GB.
🛠 Step 2: Enabling Standalone Output in Next.js
While discussing optimization strategies on Reddit, someone suggested enabling Next.js standalone output — and this was a game changer.
Add this to your config:
jsCopyEdit// next.config.js module.exports = { output: 'standalone', };
Next.js then generates a minimal .next/standalone directory during the build, containing:
The compiled app
Only the production-required dependencies
This removes the need to include the entire source or full node_modules in the final image.
🐳 Step 3: Optimizing the Dockerfile
Here’s the optimized Dockerfile:
# Use minimal Node image
FROM node:18-alpine AS base
WORKDIR /app
# Install pnpm
RUN npm install -g pnpm
# Install deps and build
FROM base AS builder
COPY . .
RUN pnpm install --frozen-lockfile
RUN pnpm build
# Final image
FROM node:18-alpine AS runner WORKDIR /app
# Copy standalone build output
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]
Now the image includes:
Only what’s needed for production
No dev dependencies or build artifacts
✅ The Final Result
🔻 Image size reduced from 4.1 GB ➝ 230 MB
📦 Lean, production-optimized container
⚡️ Faster deployments and smaller registries
🧠 Key Takeaways
pnpm improves both dependency management and Docker image size
Next.js standalone output makes shipping cleaner builds easier
Less is more when building containers for production
📚 Resources
Have you tried optimizing your Docker images with this method? I'd love to hear what worked for you or what you'd improve!