How I Reduced My Next.js Docker Image from 4.1 GB to 230 MB
May 06, 2025 |
3 min read

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!

Support

Thank you for reading! If you enjoyed this post and want to support my work, consider supporting me by leaving a comment or sharing this post with a friend.