DevOps
Dockerfile
Build smaller images with explicit layers and predictable startup.
Base and files
FROM node:22-alpineChoose a base image; pin a digest for reproducibilityWORKDIR /appSet the working directory for subsequent instructionsCOPY package*.json ./Copy dependency manifests before sourceRUN npm ci --omit=devInstall lockfile dependencies for a runtime imageRuntime
COPY . .Copy source after excluding unnecessary files with .dockerignoreENV NODE_ENV=productionSet a runtime environment defaultEXPOSE 3000Document the intended port; this does not publish itCMD ["node", "server.js"]Use exec-form startup for cleaner signal handlingBuild choices
FROM node:22-alpine AS buildName a build stageCOPY --from=build /app/dist ./distCopy artifacts from a previous stageUSER nodeDrop root privileges when filesystem permissions permitdocker build --target build -t app-build .Build a selected stage