Docker caches each instruction as a layer. If a layer changes, every later layer is rebuilt. Copying the entire repository before installing dependencies means every code change re-installs everything.
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-alpine
WORKDIR /app
COPY --from=build /app/.output ./.output
USER node
CMD ["node", ".output/server/index.mjs"]Keep the runtime boring
- Use a multi-stage build so compilers and development dependencies do not ship in the final image.
- Pin a version instead of latest. A moving tag makes yesterday’s deploy unreproducible.
- Run as a non-root user and drop capabilities you do not need.
Something to add?
Send a correctionCorrections and technical review are welcome. Tell us what we missed.