The "ERROR: Failed to Solve - Not copying non-directory" issue in Docker occurs when the COPY or ADD instruction attempts to copy a path that does not exist, is not a directory, or is excluded by .dockerignore. To resolve this, verify the source file exists relative to the build context, ensure it is not ignored, and check for typos in the file paths within your Dockerfile.
Understanding the Build Context
The root cause of this error almost always lies in the relationship between yourDockerfile location and the build context directory. When you run docker build, Docker sends the specified context (usually the current directory .) to the Docker daemon. The paths inside COPY instructions are interpreted relative to this context root, not necessarily relative to where the Dockerfile itself resides.
If you specify COPY ./src/app.py /app/ but run the build command from a parent directory, Docker looks for ./src/app.py in the parent directory. If that path does not exist there, the build fails with the non-directory error. This distinction is critical because developers often assume the context is automatically the directory containing the Dockerfile, which is only true if you explicitly pass that directory as the context argument.
Verifying Path Existence
Before diving into complex fixes, perform a simple sanity check. Ensure that the file you are trying to copy actually exists at the expected location. If your project structure is:project/
├── Dockerfile
└── src/
└── app.py
And you are building from the project directory, the command must be:
COPY src/app.py /app/
Notice that we do not use ./ before src in the COPY command if the context is the project root. Using ./src can sometimes cause ambiguity depending on how the context was passed. Always confirm the file exists using standard shell commands like ls before running the build.
Checking .dockerignore Files
A very common hidden cause for this error is the presence of a.dockerignore file in your build context. This file functions similarly to .gitignore and tells Docker which files or directories to exclude from the context sent to the daemon.
If your .dockerignore contains a rule that excludes the specific file or folder you are trying to copy, Docker will not see that file during the build process. Consequently, it treats the source path as non-existent, triggering the "Not copying non-directory" error.
To diagnose this, temporarily rename your .dockerignore file to .dockerignore.bak and attempt the build again. If the build succeeds, you have identified the culprit. You should then review your ignore rules to ensure they are not too broad. For example, avoiding patterns like *.pyc or __pycache__/ unless necessary, and ensuring you haven't accidentally excluded your main application source code.
Common Ignore Patterns
Review your.dockerignore for accidental exclusions. Common mistakes include:
- Excluding all text files with
*.txtwhen you need a configuration file. - Excluding the entire source directory due to a typo in the pattern.
- Using absolute paths in
.dockerignorewhich may behave unexpectedly across different operating systems.
.dockerignore patterns are matched against the relative paths within the context.
Handling Symlinks and Special Files
Docker'sCOPY instruction has specific behaviors regarding symbolic links and special files. If the source path points to a symbolic link that resolves to a non-directory, or if the symlink itself is broken, Docker may fail to copy it. Similarly, attempting to copy device files or named pipes will result in errors.
Ensure that any symlinks in your build context are valid and point to existing regular files or directories. If you are working in a development environment where symlinks might change frequently, consider resolving them manually before building or using ADD with caution, though COPY is generally preferred for simplicity and security.
If you are encountering this error while trying to copy a directory, ensure that the path ends with a slash if you intend to copy the *contents* of the directory, or omit the slash if you want to copy the directory itself along with its contents. However, the specific error "Not copying non-directory" usually indicates the target is not a directory at all, so double-check that you aren't accidentally pointing to a file when expecting a directory.
Debugging Strategies
When standard checks fail, use Docker's verbose output to gain deeper insight. Run the build command with the--progress=plain flag. This provides detailed logging that can help identify exactly which step fails and what paths Docker is evaluating.
docker build --progress=plain -t my-image .
Look for lines indicating the COPY step. If the log shows that the source file is missing, it confirms the context or ignore file issue. If the log suggests permission issues, ensure the user running the Docker daemon has read access to the source files.
Additionally, consider using a multi-stage build to isolate the problem. By copying files into an intermediate stage first, you can verify that the initial copy operation works before proceeding to more complex setup steps. This helps narrow down whether the issue is with the initial file transfer or a subsequent layer operation.
For related troubleshooting on Docker-specific module issues, you might find our guide on fixing Daphne Docker Django errors helpful, as similar context misconfigurations can lead to runtime failures after the build succeeds. See Fixing Daphne Docker Django ModuleNotFoundError.
Frequently Asked Questions
Why does the error persist even when the file exists?
The most likely reason is that the file is being excluded by a.dockerignore rule. Check your ignore file for patterns that might match your source file and remove or adjust them. Another possibility is that you are building from the wrong directory, changing the effective build context.
Can I copy files from outside the build context?
No, Docker strictly confines the build process to the provided context for security reasons. You cannot reference files outside the directory tree passed todocker build. You must either move the required files into the context or adjust your build command to include the correct parent directory as the context.
What is the difference between COPY and ADD regarding this error?
BothCOPY and ADD will fail with similar errors if the source path is invalid. However, ADD has additional features like automatic tar extraction and URL fetching, which can introduce other failure modes. It is generally recommended to use COPY for simple file transfers to avoid unexpected behavior.
How do I fix permissions errors during copy?
If Docker reports permission denied instead of "non-directory," ensure the user running the Docker daemon has read access to the source files. On Linux, this usually means the current user has read permissions. You can adjust file permissions usingchmod before running the build.
Does Docker Desktop handle contexts differently than CLI?
Docker Desktop uses the same build engine as the CLI, so the context rules remain identical. However, the default working directory in the GUI might differ from your terminal. Always verify the "Context" selected in Docker Desktop matches the directory containing yourDockerfile and source files.