intermediate

Dockerfile

Describe image builds through ordered instructions for base images, dependencies, source files, users, entrypoints, and commands.

A Dockerfile is build code. Instruction order controls caching and correctness: copy manifests first, install with a frozen lockfile, copy source later, build, then set runtime user and command deliberately.

					FROM node:20-bookworm-slim AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

FROM deps AS build
COPY . .
RUN npm run build

FROM node:20-bookworm-slim AS runtime
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=deps /app/node_modules ./node_modules
USER node
CMD ["node", "dist/server.js"]
				

Use `.dockerignore` to exclude `node_modules`, `.git`, tests, and local env files. Prefer `COPY` over `ADD` unless you need archive extraction.

On interviews: `COPY` vs `ADD`, `.dockerignore`, non-root users, build args versus runtime env, and separating build-time from runtime configuration.

Common pitfalls: copying the whole repo before `npm ci` destroys cache reuse; secrets in `ARG` or layers leak in image history.

The trade-off is build speed (layer caching) versus clarity and safe separation of build secrets from runtime images.

Checklist:

  • Order instructions for cache correctness.
  • Use `.dockerignore`.
  • Avoid secrets in layers or build args.
  • Run production processes as non-root when possible.