Skip to main content
Technical Systems

What Is a .dockerignore File? Defining Docker Build Inputs

Choose the context first, then exclude files according to how the image is actually built.

Understand .dockerignore through build-context boundaries, pattern scope, exceptions, Dockerfile-specific rules, cache dependencies, secret mounts, and the difference from Git ignores.

What Is a .dockerignore File? Defining Docker Build Inputs

A Docker image build works locally but fails in CI because the Dockerfile expects a generated directory that the ignore rules exclude. In another project, a broad copy instruction includes local files that were never intended to reach the builder. Both problems begin with an unclear contract about build inputs.

A .dockerignore file filters files from an applicable Docker build context before the build consumes them. It helps define what the builder can use, rather than simply listing files that should not appear in the final image. A file can be available to a build without being retained in its final stage.

The useful starting point is therefore the context and the build procedure. Determine where source, dependencies, and generated output come from, then decide which local files belong in that process. A generic ignore template cannot make those decisions for every project.

Identify the Context Independently of the Dockerfile

Docker’s build-context documentation explains the input made available to a build. In the following command, the final dot selects the current directory as the local context, while the option selects a Dockerfile elsewhere beneath it:

docker build -f docker/production.Dockerfile -t example-app .

The context does not become the docker directory merely because that is where the Dockerfile resides. Paths used to copy local context files are interpreted according to the Dockerfile instruction’s rules, not as arbitrary access to the developer’s filesystem.

For a normal local context, put its general .dockerignore at the context root. A Dockerfile-specific file such as production.Dockerfile.dockerignore can sit beside production.Dockerfile and takes precedence over the root ignore file when applicable. Review that effective file rather than assuming the root exclusions are always combined with it.

Builds can also use other context forms or named contexts. Do not assume one local ignore file governs every source available to a build. The declared inputs and access methods need to be understood together.

Exclude Files Based on the Build Strategy

For a Node.js application that installs dependencies inside the build, local node_modules usually does not belong in the context. It may contain platform-specific binaries or stale packages. Retaining the dependency manifest and lockfile while installing in the intended environment gives a clearer input model.

Generated output needs a deliberate choice. If the Dockerfile compiles the application, local dist output may be unnecessary. If CI produces a deployment artefact first and the Dockerfile copies that artefact, excluding dist can remove the very input the build requires.

The Dockerfile COPY reference describes the sources an instruction can use, including other stages. An excluded local file cannot be recovered by a later ordinary copy from that context. A file generated in a build stage is a different source and can be copied from the stage as appropriate.

Candidate exclusionOften appropriate whenCheck before excluding
Local dependency directoryDependencies are installed in the buildNo required vendored input is stored there
Generated application outputThe build generates its own outputThe Dockerfile does not consume a CI artefact
Git metadataBuild identity is supplied separatelyVersion generation does not require it
Test reports and logsThey are not build inputsNo packaging step intentionally consumes them
Local environment filesRuntime configuration is supplied separatelyAny retained example contains no secrets

Keep the rules tied to that strategy. A test image can legitimately need fixtures and tests that a production image does not. Excluding all test-related paths everywhere can weaken the verification stage without making the production image safer.

Use Docker Pattern Rules Rather Than Assuming Git Semantics

Docker ignore syntax resembles familiar globbing, but it is a distinct contract. The ignore-file implementation documents preprocessing such as comments beginning with a hash character and cleaning pattern paths. Do not substitute shell expansion or Git’s directory rules for the builder’s behaviour.

An illustrative starting file is:

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

Here double-star patterns express matching across directory depth. The final exception retains the root .env.example if it matches the earlier exclusion, so that file must be reviewed as intentionally public build input. The example is not a complete secret detector or a suitable policy for every repository.

Rule order matters: later matching exclusions or exceptions affect the result. Review broad exclusions together with their exceptions rather than reading each line independently. A later rule can undo the result a reader expected from an earlier one.

Check depth explicitly. A pattern matching Markdown files directly under the context root is not necessarily a recursive exclusion. Use the documented double-star behaviour when recursion is intended, and verify root and nested examples when reviewing a change.

Docker also treats the Dockerfile and ignore file specially: they may still be sent because the builder needs them even when listed as ignored, while restrictions apply to copying them into the image. This is one reason the shorthand ignored means never transmitted is too broad.

Selecting local build inputs
Selecting local build inputs Selected local context directory Effective ignore rules Included build inputs Excluded local files Dockerfile instructions and build stages Selected final image contents
The effective ignore rules filter the context; the Dockerfile then determines how available inputs contribute to stages.

Treat Secret Handling as a Separate Control

Excluding known local credential files reduces accidental availability to the builder. It does not find secrets embedded in source, remove credentials from base images, or control every remote download performed during a build. Inspect those other input paths independently.

Docker’s build-secret documentation describes secret mounts and SSH mounts for suitable build-time access. Build arguments and environment variables are not appropriate substitutes for secret handling simply because they are convenient to pass from CI.

A secret mount can make a credential available to a particular operation without intentionally copying it into a normal image layer. The command using the secret can still disclose it through output or generated files. Review what the step does, not only how the secret reaches it.

Deleting a sensitive file in a later layer is also not equivalent to preventing its earlier inclusion. Keep secret material out of ordinary copy paths, and use approved mechanisms for the build and runtime separately. The image’s final visible directory listing is not a complete history of its inputs.

Relate Ignore Rules to Cache Dependencies

Docker’s cache guidance recommends limiting unnecessary context and ordering build steps around their inputs. A dependency-installation step can often copy manifests before application source, allowing reuse when only unrelated source files change.

An excerpt might therefore copy package.json and package-lock.json before running npm ci, then copy the files needed for compilation. The complete Dockerfile still needs an appropriate base, working directory, build tools, and runtime stage. Ignore rules should retain every input those steps require.

Do not assume every extra file always invalidates every cached layer. The relevant dependency is what a particular instruction consumes and how the builder determines its cache key. A broad copy increases the inputs that can matter, while targeted copies can keep dependencies narrower.

Context filtering is not a complete reproducibility strategy. Base-image references, package sources, tool versions, and external downloads can change results even when the local file set is stable. Preserve the relevant versions and build records alongside the ignore policy.

Keep Git Tracking and Build Availability Separate

Git’s ignore documentation concerns intentionally untracked files; ignore rules do not automatically stop Git tracking an already tracked file. Docker does not treat .gitignore as the general policy for its build context.

A local file can be ignored by Git and still be available to Docker unless the applicable build rules exclude it. Conversely, a tracked documentation file can be excluded from a build because it is unnecessary there. Neither decision establishes the other.

This can explain a local-versus-CI difference without any change in the Dockerfile. A developer’s working directory may contain an untracked generated file that the build happens to consume, while a clean checkout does not. Alternatively, an ignored local configuration file may accidentally alter the local result. Compare the available inputs, not only the repository revision, when investigating the difference.

If the build intentionally requires a generated artefact, make its production an explicit prerequisite and identify the version being consumed. If it does not require that local file, remove the accidental dependency through an appropriate context or copy policy.

Review both policies when adding generated output, configuration examples, or credentials. The question for Git is whether the repository should track the file. The build question is whether this particular image-building process should receive it. Keeping those decisions separate prevents a false sense of protection.

Verify the Effective File Set When the Build Changes

Review the command, selected context, Dockerfile, effective ignore file, and copy sources together. Test the intended build process in the project’s normal verification workflow when those inputs change, and inspect the resulting image or artefact for the properties that matter.

Include representative root and nested paths, exception ordering, and any Dockerfile-specific policy. A successful build establishes that its required inputs were available; it does not establish that no unintended file was available. Those are separate checks.

A useful .dockerignore remains small enough to understand and specific enough to the build. Its purpose is a deliberate input boundary that supports the intended image, rather than an inherited list of exclusions nobody can explain when the next build fails.