Skip to content
Development

What Is a .dockerignore File? Build Context, Patterns, and Common Mistakes

Make the files available to a container build an intentional choice.

What Is a .dockerignore File? Build Context, Patterns, and Common Mistakes

Key takeaways

  • A .dockerignore file excludes paths from the build context used by Docker.
  • The build command's context argument determines the root against which ordinary context paths are resolved.
  • Ignoring a file affects build inputs and only changes image size if that file would otherwise be included.
  • Build-time secrets need a secret mechanism, and ignore rules must preserve the files the Dockerfile needs.

A .dockerignore file tells Docker which paths to exclude from a build context. Those excluded files are unavailable to ordinary context-based COPY and ADD instructions.

Imagine a Node.js project containing source code, installed dependencies, test reports, and a local environment file. The application needs its source and package manifests to build. It does not need to inherit the developer’s dependencies or local credentials.

The ignore file makes that distinction before a broad copy instruction can bring unwanted inputs into the image.

Find the Context Before Writing Rules

Consider this command, run from the project root:

docker build -f docker/Dockerfile .

The final dot selects the current directory as the build context. The -f option selects the Dockerfile; it does not change the context to the docker directory.

Place the ordinary .dockerignore at the context root.

Docker also supports a Dockerfile-specific file such as docker/Dockerfile.dockerignore. When present for that Dockerfile, it takes precedence over the root ignore file. Do not assume both sets of rules are automatically combined.

The build-context documentation explains these locations and pattern behavior.

Start With the Project’s Actual Inputs

For this example, where dependencies and output are produced inside the build, a starting file is:

node_modules/
.git/
coverage/
dist/
**/*.log
.env
.env.*
!.env.example

The final exception keeps the sample environment file available after the broader exclusion. Only do this if the sample contains safe placeholder values.

The Dockerfile might then copy its inputs explicitly:

COPY package.json package-lock.json ./
RUN npm ci
COPY src/ ./src/
RUN npm run build

This is a fragment, not a complete Dockerfile. Other required configuration and static assets must also be copied.

If the real build copies an already-generated dist/ directory instead, excluding that directory would be wrong. Ignore rules should follow the build process rather than a generic checklist.

Read Patterns as Ordered Rules

An exclamation mark introduces an exception, and the last matching rule determines whether a path is included.

Docker’s ** pattern can match across directory levels. In the example, **/*.log covers logs below nested directories as well as the root.

Keep overlapping rules understandable. A later broad exclusion can undo an earlier exception.

When a previously working COPY begins reporting a missing source, check the context root and active ignore file before assuming the file was deleted.

Context Size and Image Size Are Different

A file can be available in the context without ending up in the final image.

If the Dockerfile copies only package files and source, ignoring local test reports may reduce context work without changing image size. If it uses COPY . ., those reports may otherwise become image contents.

Builder behavior also matters. Modern builders can avoid transferring some unused files, so “Docker always uploads the whole directory” is an unreliable explanation.

Focus on which inputs each build instruction actually consumes.

Keep Cache Dependencies Deliberate

Copying package manifests before changing source can allow the dependency-installation step to reuse its cache when only application code changes.

A broad early copy makes that step depend on more files. Excluding irrelevant files reduces opportunities for unrelated edits to invalidate cached work.

Docker’s cache optimization guide discusses context size and instruction ordering together.

Neither technique guarantees reproducibility. Dependency versions, base images, and external downloads remain separate inputs.

Ignore Rules Are Not Secret Management

Excluding local credentials reduces accidental exposure, but a build may legitimately need temporary access to a private package registry.

Use the builder’s supported secret mounts for that access. Copying a secret into an image and deleting it in a later layer does not reliably remove the earlier copy.

A secret mount also cannot prevent the command using it from deliberately writing the secret into an output file. The build step still needs careful handling.

.gitignore Controls a Different Tool

A file excluded from Git tracking can still be present in a local Docker context. Docker exclusions likewise do not stop a file being committed.

Review both boundaries when the project layout changes.

For the Node.js application, the desired result is straightforward: source and declared dependencies produce the image, while local caches, credentials, and stale output do not quietly become part of its inputs.

The right build context contains the required inputs without inheriting everything from a developer's machine.
Top