order-layers
npm install reruns on every Docker build? Fix Dockerfile layer order so dependency installs cache until the lockfile actually changes.
On this page
If COPY . . sits above your install command, every source-file edit invalidates the copy layer — and everything after it, including the install. That is why npm ci (or pip install, or bundle install) reruns from scratch on every build even though the dependencies didn't change. This rule flags installs that run after the full application source has been copied.
What the rule catches
FROM node:22-slim
WORKDIR /app
COPY . .
RUN npm ci
CMD ["node", "server.js"]Scanning this file reports:
⚠ WARN [docker-doctor/order-layers]
Running package installation command 'npm ci' after copying application files (at line 3). This invalidates the cache on any code changes.Why it matters
Docker caches layers top-down: the first changed instruction invalidates everything below it. Dependency manifests change rarely; source files change constantly. Put the rarely-changing thing first — copy just the manifest and lockfile, install, then copy the source — and dependency installation caches across builds. This one reordering routinely takes CI builds from minutes to seconds, and it costs four lines.
How to fix it
Copy dependency definition files (like package.json, lockfiles) and run install commands BEFORE copying the rest of the application source code.
FROM node:22-slim
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
CMD ["node", "server.js"]The same pattern applies to every ecosystem: requirements.txt before pip install, go.mod/go.sum before go mod download, Gemfile before bundle install, Cargo.toml before the build. Pair it with a .dockerignore so stray files can't invalidate the copy layer either.
Rule details
- Rule key —
docker-doctor/order-layers - Category — Performance
- Default severity —
warning - Applies to — Dockerfiles
Explain this rule from the CLI:
npx @docker-doctor/cli@latest rules explain docker-doctor/order-layersChange its severity — or turn it off — in your config file:
// docker-doctor.config.ts
export default {
rules: {
"docker-doctor/order-layers": "off",
},
};Severity affects the health score: error findings cost more points than warning, and info costs the least.