Without it, node_modules, .git and .env files end up slowing builds or, worse, inside your image.
The build context is everything in the directory you pass to docker build. A `.dockerignore` file in the root of the context lists patterns to exclude, much like .gitignore.
Why it matters:
- Speed: sending a 2 GB
node_modulesor.gitdirectory to the builder wastes time on every build. - Cache stability:
COPY . .checksums everything it copies. If.gitor log files are included, the cache breaks whenever they change, even when your code didn't. - Security:
.envfiles, SSH keys and cloud credentials sitting in the project folder get baked into the image byCOPY . ., and anyone who pulls the image can read them. - Correctness: copying your host's
node_modules(built for macOS) over the container's Linux-built ones causes confusing native-module errors.
Syntax essentials:
- One pattern per line;
#starts a comment. - Paths are relative to the context root;
*matches within a path segment,**across any number of directories. !patternre-includes something excluded earlier, and the last matching line wins.- Some teams invert it: start with
*, then allow only what's needed with!srcand!package*.json.
The file must sit at the root of the build context, not necessarily next to the Dockerfile. With BuildKit you can also give a Dockerfile its own ignore file by naming it after it, for example Dockerfile.prod.dockerignore.
Example
# .dockerignore
.git
.gitignore
**/node_modules
**/__pycache__
*.log
dist/
coverage/
# secrets and local config
.env
.env.*
!.env.example
**/*.pem
# not needed inside the image
Dockerfile*
compose*.yaml
README.mdRemember
- .dockerignore excludes files from the build context
- It speeds up builds, stabilises the cache and keeps secrets out
- It must be at the context root; ! re-includes; last match wins
Watch out for
- Relying on .gitignore — Docker ignores it; only .dockerignore affects the build context.