Docker Foundations·Ship the environment with the app

.dockerignore and build speed

A small build context and a well-ordered Dockerfile keep rebuilds fast.

Beginner 13 min read Lesson 3 of 300 Challenge included
What you will be able to do
  • Add a .dockerignore to shrink the build context.
  • Copy dependency manifests before source to preserve cache.
  • Order commands so the most stable layers come first.
  • Use a multi-stage build to keep the final image small.

In plain English

When you run docker build, Docker first sends the build context, the folder around your Dockerfile, to the daemon before it builds anything. A .dockerignore file lists files and folders to leave out, such as node_modules and .git, so the context stays small and secrets stay out of the image. Docker caches each layer and reuses it only while its inputs are unchanged, so you copy dependency manifests before source code and keep expensive installs early. Because layers build from top to bottom, ordering matters: a change to source should not invalidate an expensive dependency install. A multi-stage build does the work in a first stage and copies only the finished result into a tiny final image.

Step by step

  1. 1Create a .dockerignore that excludes node_modules, .git and build output.
  2. 2Copy package*.json first, install dependencies, then copy the source.
  3. 3Build once, then change only a source file and rebuild to see the cache hit.
  4. 4Split the build into a build stage and a runtime stage with COPY --from.
  5. 5Check the final image size with docker images.
DockerfileDockerfile
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
ENV NODE_ENV=production
COPY --from=build /app/dist ./dist
USER node
EXPOSE 3000
CMD ["node", "dist/index.js"]

Common mistakes

  • Copying all of the source before installing dependencies invalidates the install cache on every code edit.
  • Sending the whole project as the build context makes every build slow and can leak files into the image.
  • Keeping the compiler and dev dependencies in the final image bloats it unnecessarily.
  • Running npm install instead of npm ci can skip the lockfile and produce unrepeatable builds.
Your turn

Write a cache-friendly Dockerfile

Medium

Write a Dockerfile that copies package*.json first, runs npm ci, copies the source, builds, and serves the built output from a runtime stage.

DOCKERFILE · starter
FROM node:22-alpine
COPY . .
RUN npm ci
CMD ["node", "index.js"]
Check your understanding before moving on.
Knowledge checkQuestion 1

What is the main purpose of a .dockerignore file?

Select an answer to continue
Study tools

Make it yours.

Keep a private note for this lesson, then turn the key ideas into flashcards you can revisit.

Sign in to save notes and flashcards.Both are private to your account and stay with your progress.
Sign in
Finished reading?

Lock in what you just learned.

Mark this lesson complete to save your place and move one step closer to the certificate.

Lesson 3 of 300 · 0% of course