In this article
For a local Docker build, two paths determine how to reason about ignored files:
- The build-context root, supplied as the command’s positional path.
- The selected Dockerfile, chosen by default or with
-f/--file.
These are separate inputs. Selecting a Dockerfile in a subdirectory does not relocate the context root. It can, however, change which Dockerfile-specific ignore file Docker uses.
The key rule is: a Dockerfile-specific ignore file takes precedence over the .dockerignore at the build-context root when both exist. (Docker build-context documentation)
This article synthesizes Docker’s documented contract for local directory contexts. It does not report a hands-on build test or claim validation across particular Docker, Buildx, or BuildKit versions. Remote contexts, empty contexts, additional named contexts, and detailed ignore-pattern semantics are outside its scope.
Separate the context from the Dockerfile
Consider this command:
docker buildx build -f docker/build.Dockerfile .
The final . is the local build context. Docker defines the build context as “the set of files that your build can access” and accepts a relative or absolute local directory path as a context. (Docker build-context documentation)
The -f docker/build.Dockerfile option selects the Dockerfile. Buildx expresses these as separate parts of its command:
docker buildx build [OPTIONS] PATH | URL | -
The -f or --file option specifies the Dockerfile’s location, while the positional PATH supplies the context. (Docker Buildx CLI reference)
For the example, those inputs resolve to:
Context root: ./
Selected Dockerfile: ./docker/build.Dockerfile
The Dockerfile is nested under docker/, but the context remains .. If -f is omitted, Buildx instead uses a file named Dockerfile at the context root. (Docker Buildx CLI reference)
This separation has a useful consequence: changing only -f can change the applicable Dockerfile-specific ignore file without changing the context boundary. Conversely, changing the positional context path changes the root used for the ordinary .dockerignore and for local source-path reasoning. Treating those two inputs independently prevents a nested Dockerfile’s directory from being mistaken for the context root.
The two possible ignore-file locations
The ordinary .dockerignore is located at the root of the build context. (Docker build-context documentation)
<context-root>/.dockerignore
Its purpose is to exclude files and directories from the build context. (Dockerfile reference) With . as the context, the root file is therefore ./.dockerignore, even when the selected Dockerfile is nested.
Docker also documents an ignore file associated with a particular Dockerfile. It must sit beside that Dockerfile and use the Dockerfile’s complete name followed by .dockerignore. Documented examples include build.Dockerfile.dockerignore, lint.Dockerfile.dockerignore, and test.Dockerfile.dockerignore. (Docker build-context documentation)
A compact project tree makes the distinction visible:
project/
├── .dockerignore
├── app/
│ └── config.json
└── docker/
├── build.Dockerfile
└── build.Dockerfile.dockerignore
For docker/build.Dockerfile, the matching specific file is:
docker/build.Dockerfile.dockerignore
A file named docker/.dockerignore does not match the documented Dockerfile-specific convention: the specific file uses the Dockerfile’s name and resides in the same directory. (Docker build-context documentation)
Quick lookup table
Each row starts with context . and shows the relevant paths.
| Build inputs | Matching specific file | Ignore-file selection |
|---|---|---|
No -f, so Buildx selects ./Dockerfile by default. (CLI reference) |
./Dockerfile.dockerignore, using the documented same-directory naming convention. (Context documentation) |
Docker uses the matching specific file in preference to ./.dockerignore when both exist. If no matching specific file exists, inspect the context-root file. (Context documentation) |
-f prod.Dockerfile selects ./prod.Dockerfile. (CLI reference) |
./prod.Dockerfile.dockerignore, derived from the selected filename. (Context documentation) |
Docker gives the matching specific file precedence over ./.dockerignore; otherwise, inspect the root file. (Context documentation) |
-f docker/test.Dockerfile selects a nested Dockerfile while . remains the context. (CLI reference) |
./docker/test.Dockerfile.dockerignore, beside the selected Dockerfile. (Context documentation) |
Docker gives the matching specific file precedence over the context-root ./.dockerignore; otherwise, inspect the root file. (Context documentation) |
The fallback location remains tied to the context root, not to the selected Dockerfile’s directory. This lookup procedure is a synthesis of Docker’s documented Dockerfile selection, ignore-file naming, and precedence rules.
File-selection decision tree
Use this sequence before evaluating a local COPY source:
-
Find the positional context path.
Indocker buildx build -f docker/build.Dockerfile ., it is.. -
Resolve the context root.
This defines the set of local files the build can access. (Docker build-context documentation) -
Identify the selected Dockerfile.
Without-f, useDockerfileat the context root. With-for--file, use the specified path. (Docker Buildx CLI reference) -
Derive the specific ignore-file path.
Append.dockerignoreto the selected Dockerfile’s complete filename and check the same directory. (Docker build-context documentation) -
Determine which file Docker uses.
Give the matching Dockerfile-specific file precedence if it exists; otherwise, inspect<context-root>/.dockerignore. (Docker build-context documentation) -
Only then evaluate local source references.
Worked COPY example
Suppose docker/build.Dockerfile contains:
COPY app/config.json /opt/app/config.json
For this invocation:
docker buildx build -f docker/build.Dockerfile .
start from . as the context root. The specific ignore-file candidate is docker/build.Dockerfile.dockerignore; the ordinary candidate is ./.dockerignore. Docker gives the specific file precedence when both exist. (Docker build-context documentation)
Finally, interpret app/config.json relative to the context root, not relative to the docker/ directory containing the Dockerfile. Docker documents local source paths as relative to the root of the build context. (Dockerfile reference)
For this example, the completed troubleshooting checklist is:
- Context root:
./ - Selected Dockerfile:
./docker/build.Dockerfile - Specific ignore candidate:
./docker/build.Dockerfile.dockerignore - Root ignore candidate:
./.dockerignore COPYsource basis:./app/config.json, relative to the context root
That order avoids the central mistake: deciding whether a COPY source is available by looking only at the root .dockerignore. Establish the context, identify the Dockerfile, select the relevant ignore file, and only then reason about the source path.
No comments yet