Build Cache & .dockerignore
Ordering for the Cache
Rebuilding an image from scratch every time you change one line of code would make development painfully slow. Docker avoids this with the build cache: it remembers the layers from your last build, and when it builds again, it reuses every layer that hasn't changed - all the way down the Dockerfile until it hits the first instruction whose input actually changed. From that point on, everything after it rebuilds, even if those later steps look unrelated. So the practical rule is: order instructions from least to most frequently changing, so the expensive steps (installing dependencies) stay cached and only the cheap, fast-changing step (copying your code) reruns.
# ✅ deps cached until package.json changes - code edits rebuild in seconds
COPY package*.json ./
RUN npm ci
COPY . .
# ❌ any code edit invalidates the cache → full npm ci every build
COPY . .
RUN npm ci
.dockerignore - Small Images, Safe Images
COPY . . copies everything in the build context - including things that should never enter an image:
# .dockerignore
.git
node_modules
*.log
.env ← live secrets baked into a distributable image = breach
backup.tar
Danger: An image is not private storage. Anyone who can pull it can read every file in every layer - even files deleted in a later layer are still in the earlier one. A .env with production keys inside an image is a security incident, not a code smell.
Goal: The Slim the Image, Save the Secrets lab hands you exactly this incident: a 40MB-heavier image with live secrets inside. Fix it with .dockerignore.