Docker

Lesson 04

Multi-stage builds

Separate build tooling from the final runtime image so production containers contain only what they need to run.

Good Code

Dockerfile
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

FROM deps AS build
COPY . .
RUN npm run build

FROM node:22-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/.next/standalone ./
COPY --from=build /app/.next/static ./.next/static
CMD ["node", "server.js"]

Bad Code

Dockerfile
FROM node:22-alpine
WORKDIR /app

COPY . .
RUN npm install
RUN npm run build

CMD ["npm", "start"]

Review Notes

What to review

Good Code

The good version keeps install and build tooling in earlier stages and copies only runtime artifacts into the final image.

Bad Code

The bad version ships source files, dev dependencies, and build tools in the same image that runs production.

Takeaways

  • Multi-stage builds reduce final image size and separate build concerns from runtime concerns.