Comparing next start and next standalone with docker

Published on May 03, 2023

I wrote about how to use nextjs with docker.

I wanted to compare using next standalone like in the article and just using next start.

I describe the new docker file I used for using next start in docker at the bottom of this article. But let’s jump straight to the learnings.

Docker Image Size

The standalone mode I used in my original article creates a docker container of 230MB.

The next start mode creates a docker container of 750MB.

If you’re passing around many docker containers throughout the day the lower size of standalone mode can be a big difference.

Static Asset serving

Standalone next build provides you a separate set of static assets that you can use in AWS S3 or similar instead of your docker container.

This is a big advantage of standalone mode if you have many static assets or your site is very busy.


The next start method is easier to setup in docker. It’s also the default way to run nextjs and will always support all next features.

The standalone method is a bit more complex to setup in docker but once you set it up it doesn’t change very often.

The standalone image is less than half the size of the full app method.

I’m going to continue using standalone for now!

Appendix: The next start dockerfile used

To setup the test we use the following dockerfile:

# A container with pnpm and python3 is required
FROM node:18-alpine as pnpm_base

RUN npm i --global --no-update-notifier --no-fund pnpm@7
RUN apk add --no-cache g++ make py3-pip libc6-compat

# run fetch in a separate step to avoid re-fetching deps on every change
FROM pnpm_base as fetched_deps
ENV NODE_ENV production
COPY pnpm-lock.yaml ./
RUN pnpm config set store-dir /workdir/.pnpm-store
RUN pnpm fetch

# install all deps from cache
FROM fetched_deps as with_all_deps
COPY . ./
RUN pnpm install --offline

# Build the BE
# the main issue with building everything is the FE depends on a running BE
FROM with_all_deps as builder
RUN pnpm --filter='*frontend' build
RUN pnpm --filter='*frontend' deploy pruned --prod

# Production image - only take pruned assets
FROM node:18-alpine AS runner
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 app
RUN adduser --system --uid 1001 app
USER app

COPY --chown=app:app --from=builder /app/apps/frontend/ /


CMD ["npm", "start"]
Darragh ORiordan

Hi! I'm Darragh ORiordan.

I live and work in Sydney, Australia building and supporting happy teams that create high quality software for the web.

I also make tools for busy developers! Do you have a new M1 Mac to setup? Have you ever spent a week getting your dev environment just right?

My Universal DevShell tooling will save you 30+ hours of configuring your Windows or Mac dev environment with all the best, modern shell and dev tools.

Get DevShell here: ✨

Read more articles like this one...

List of article summaries


How to add canonical meta tag in NextJs

It’s important to add a canonical meta tag to your pages to improve SEO or to avoid issues with query params in crawled pages.

You can easily add a canonical meta tag in NextJs by using the next/head component.


Open Telemetry in NextJs and NestJs

I wrote about how to use open telemetry with NestJs and React previously.

I wanted to add open telemetry to my NextJs app that calls a NestJs backend. The paradigm of SSR preferred by NextJs is a bit different than the CSR paradigm of React.

I’ll describe the differences and how I added open telemetry to NextJs that propagates to other backend APIs.


Force RSA key support for Azure DevOps Git SSH

If you’re using Azure DevOps Git SSH you have to use an RSA key. This is because Azure DevOps doesn…