You’re deep into your containerization project, feeling confident about your Dockerfile setup, when suddenly—boom! Your build crashes with that dreaded error message: COPY failed: file not found in build context or excluded by .dockerignore
.
If you’ve landed here, you’re probably staring at your terminal wondering why Docker can’t find a file that’s sitting right there in your project directory. This error is actually one of the most common Docker build issues, and once you understand what’s happening behind the scenes, you’ll be able to fix it quickly and prevent it from happening again.
1. Understanding the Docker Build Context (The Foundation)
Before we jump into solutions, it’s crucial to understand what Docker’s “build context” actually means. The build context is the set of files that your build can access. The positional argument that you pass to the build command specifies the context that you want to use for the build.
When you run docker build .
, that dot (.) tells Docker to use your current directory as the build context. Here’s what happens:
- Docker packages all files and directories in the specified context
- Sends this entire package to the Docker daemon
- The daemon can only access files within this context during the build process
- Any COPY or ADD commands in your Dockerfile must reference files within this context
Think of the build context as Docker’s “workspace”—it simply cannot access anything outside of this designated area, no matter how you structure your COPY commands.
2. The Most Common Causes of This Error
Based on real-world scenarios and community discussions, here are the primary culprits behind the “file not found in build context” error:
Wrong Working Directory
You’re running docker build
from the wrong location. If your Dockerfile expects files to be in a certain relative position, running the build command from a different directory will break those assumptions.
Files Outside Build Context
You cannot COPY ../something /something, because the first step of a docker build is to send the context directory (and subdirectories) to the docker daemon. Any files located outside your build context directory are completely invisible to Docker.
.dockerignore Exclusions
Your file might be explicitly excluded by patterns in your .dockerignore
file, making it unavailable even though it exists in the build context.
Incorrect File Paths
Simple typos in file names or paths within your COPY commands can trigger this error.
Build Context Confusion
Using absolute paths instead of relative paths, or misunderstanding how Docker interprets file locations within the context.
3. Step-by-Step Debugging Process
When you encounter this error, follow this systematic debugging approach:
Step 1: Verify Your Current Location
pwd # Check where you're running docker build from
ls -la # List all files in your current directory
Step 2: Examine Your Build Command
Make sure you’re specifying the correct build context:
# If your Dockerfile is in the current directory
docker build .
# If your Dockerfile is elsewhere but context should be current directory
docker build -f path/to/Dockerfile .
# If both Dockerfile and context are in a different location
docker build path/to/context
Step 3: Check Your Dockerfile COPY Commands
Review each COPY instruction in your Dockerfile:
# ✅ Good: Relative path within context
COPY ./src/app.py /app/
# ❌ Bad: Absolute path outside context
COPY /home/user/project/app.py /app/
# ❌ Bad: Parent directory reference
COPY ../config.json /app/
Step 4: Inspect .dockerignore
Check if your file is being excluded:
cat .dockerignore
# Look for patterns that might match your file
Step 5: List Build Context Contents
When you run docker build, the CLI sends the files and folders to build to the Docker engine. This set of files and folders becomes the build context. To see exactly what Docker sees, create a temporary Dockerfile that lists the context:
FROM alpine
RUN find /tmp/build-context -type f
COPY . /tmp/build-context
4. Proven Solutions That Actually Work
Solution 1: Restructure Your Project Layout
The most robust approach is organizing your project so that all necessary files are within the build context:
project/
├── docker/
│ └── Dockerfile
├── src/
│ ├── app.py
│ └── requirements.txt
├── config/
│ └── app.conf
└── .dockerignore
Then build with:
# From project root
docker build -f docker/Dockerfile .
Solution 2: Adjust Your Build Context
Instead of changing your project structure, change where you run the build:
# If your files are in a parent directory
cd ..
docker build -f project/Dockerfile .
# Or specify a different context path
docker build -f ./Dockerfile ../
Solution 3: Fix .dockerignore Issues
Any paths listed in .dockerignore will be excluded from the build context. Common fixes include:
# ❌ This excludes ALL .json files
*.json
# ✅ This excludes only package-lock.json
package-lock.json
# ✅ Un-ignore specific files in ignored directories
node_modules/
!node_modules/important-file.js
Solution 4: Use Multi-Stage Builds for Complex Scenarios
When you need files from multiple locations, multi-stage builds can help:
# Stage 1: Gather dependencies
FROM alpine AS deps
COPY requirements.txt .
RUN pip install -r requirements.txt
# Stage 2: Build application
FROM python:3.9-slim
COPY --from=deps /usr/local/lib/python3.9/site-packages/ /usr/local/lib/python3.9/site-packages/
COPY src/ /app/
WORKDIR /app
CMD ["python", "app.py"]
5. Real-World Example Walkthrough
Let’s work through a common scenario that trips up many developers:
Initial Setup:
my-app/
├── frontend/
│ ├── Dockerfile
│ └── package.json
├── backend/
│ ├── src/
│ └── requirements.txt
└── shared/
└── config.json
Problematic Dockerfile (in frontend/):
FROM node:16
COPY package.json .
COPY ../shared/config.json ./config/ # ❌ This will fail!
RUN npm install
The Fix: Either restructure the project or change the build context:
# Option 1: Build from project root
cd my-app
docker build -f frontend/Dockerfile .
Update the Dockerfile:
FROM node:16
COPY frontend/package.json .
COPY shared/config.json ./config/ # ✅ Now accessible!
RUN npm install
6. Best Practices for Avoiding This Error
Keep Build Contexts Minimal
When a Docker image is built, the entire Docker context — e.g., the root of your project — is sent to the Docker daemon before the COPY or ADD commands are evaluated. This can be pretty expensive, especially if you have many dependencies, large data files, or build artifacts in your project.
Create focused build contexts:
# ✅ Good: Specific context
docker build -f dockerfiles/web.Dockerfile ./web-app
# ❌ Avoid: Entire repository as context
docker build .
Master .dockerignore Patterns
A properly structured .dockerignore can help reduce build time and prevent accidental inclusion of sensitive files:
# Development files
.git/
.env
*.log
.DS_Store
# Dependencies (if you install them in container)
node_modules/
venv/
# Build artifacts
dist/
build/
*.pyc
__pycache__/
# Documentation
README.md
docs/
Use Relative Paths Consistently
Always use relative paths in your COPY commands:
# ✅ Correct
COPY ./src /app/src
COPY config.json /app/
# ❌ Incorrect
COPY /absolute/path/file.txt /app/
COPY ../outside/context.json /app/
Leverage Build Arguments for Flexibility
For files that might be in different locations across environments:
ARG CONFIG_PATH=./config
COPY ${CONFIG_PATH}/app.conf /app/config/
7. Advanced Troubleshooting Techniques
Using BuildKit for Better Error Messages
With Docker Desktop for Mac 4.6, that’s history refers to performance improvements, but BuildKit also provides clearer error messages:
DOCKER_BUILDKIT=1 docker build .
Debugging with Verbose Output
Get detailed information about what Docker is processing:
docker build --progress=plain --no-cache .
Inspecting Build Context Size
Monitor how much data you’re sending to Docker:
# Watch for "sending build context to Docker daemon" message
docker build . 2>&1 | grep -i context
8. Prevention (To Avoid Repeating the Same Error)
Project Organization Templates
Start new projects with a Docker-friendly structure:
project/
├── .dockerignore
├── docker-compose.yml
├── Dockerfile
├── src/
│ └── [application code]
├── config/
│ └── [configuration files]
└── scripts/
└── [build/deploy scripts]
Automated Testing
Include build tests in your CI pipeline:
# Simple test to ensure Docker build succeeds
docker build -t test-image .
docker run --rm test-image echo "Build successful"
Documentation Standards
Document your build requirements clearly:
## Building the Docker Image
1. Ensure you're in the project root directory
2. Run: `docker build -t my-app .`
3. Required files: src/, config/app.conf, requirements.txt
The “COPY failed: file not found in build context” error might seem mysterious at first, but it’s actually Docker’s way of enforcing a clear separation between your local filesystem and the container build environment. By understanding build contexts, organizing your projects thoughtfully, and following the debugging steps outlined above, you’ll rarely encounter this issue again.
Remember: Docker can only see what you explicitly include in the build context. Keep your contexts focused, use .dockerignore wisely, and always use relative paths in your COPY commands. With these practices in place, your Docker builds will be faster, more predictable, and far less frustrating.