1.1 GB for a 3 KB app?
The full node:20 image is over a gigabyte — compilers, tools and docs your app never uses. Big images pull slowly, cost storage and carry more vulnerabilities. A multi-stage build builds and tests in one stage, then copies only what's needed into a small final image that runs as a non-root user.
Before and after
FROM node:20-alpine AS build WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm test FROM node:20-alpine WORKDIR /app ENV NODE_ENV=production COPY package*.json ./ RUN npm ci --omit=dev COPY --from=build /app/server.js /app/menu.js ./ USER node EXPOSE 3000 CMD ["node", "server.js"]
- -alpine and -slim bases are far smaller than the full image.
- Distroless images go further: no shell at all.
- docker history shows which layer is heavy.