Without a .dockerignore file, the build sends your entire project folder to the builder, and a line like COPY with a dot can put all of it into the image. That can include env files, private keys, git history, test data and local config. Exclude them by default and copy named paths.
How the leak happens
When you run a build, the directory you point at is the build context. Everything in it is available to COPY and ADD. A common line looks like this.
COPY . /app
That copies every file the builder can see, not only the code. Developers often have files in the project root that were never meant to ship: a local env file with a database URL, a cloud credentials file, a key used for a test, or an editor backup.
The Docker build guidance describes the ignore file as supporting exclusion patterns similar to gitignore, and says it keeps irrelevant files out of the build context without restructuring your repository.
What to exclude
Start with a deny-by-default idea and add exceptions, or at least cover these categories.
- Secrets and local config. Env files, key and certificate files, credential folders, anything named like a token.
- Version control data. The git directory holds full history, including commits that once contained a secret.
- Dependencies you will reinstall. Local module folders and virtual environments, which can also differ from what the image should install.
- Build output and caches. Old artifacts, coverage reports, logs.
- Docs and tests that the runtime does not need.
- The Dockerfile and the ignore file itself, which rarely need to be in the image.
A starting file might read:
.git
.env
.env.*
*.pem
*.key
node_modules
__pycache__
*.log
coverage
dist
Adjust it to your stack. If the app needs a built folder, copy it from a build stage instead.
Allowlist style
A safer pattern for sensitive projects is to ignore everything and then re-include what the build needs.
*
!src
!package.json
!package-lock.json
New files then stay out unless someone adds them on purpose. The tradeoff is that builds fail until you add a needed path, which is a feature rather than a bug.
Pair it with narrow COPY lines
The ignore file is a safety net. The better habit is to copy specific paths so the image holds what you chose. Combined with a multi-stage build, the final stage then receives a small set of files.
How to check what shipped
- Build the image.
- Start a container with a shell or export the filesystem.
- List the app directory and look for anything you did not expect.
- Search for files with key, env or pem in the name.
Also check old images. Tags built before you added the ignore file may still hold what you meant to exclude, and those layers remain in the registry until removed.
Safeguard's SBOM and dependency scanning, plus policies and gates, can add a check to your pipeline so a risky image fails before it is pushed. A free scan is the quickest way to try it on an existing image.
Quick check
Does the ignore file stop ADD from fetching a URL?
No. It filters files in the local build context. Remote downloads are a separate question, covered in the ADD versus COPY guide.
Is gitignore enough?
No. The builder reads the build context from the folder, not from git, so ignored-by-git files can still be copied unless the docker ignore file excludes them.
Sources
Last reviewed: 19 October 2026.