Topic 2.3
Build Context & .dockerignore
In one line
Everything in your build context gets sent to the Docker daemon before the build even starts — an unfiltered context silently slows every single build and can leak secrets into your image.
Think of it like this
Packing a suitcase for a weekend trip by dumping your ENTIRE closet into it instead of picking just what you need — heavier, slower to pack, and you might accidentally pack something private you didn't mean to bring (like your diary).
Key ideas
- 01
The BUILD CONTEXT is the directory you point
docker buildat (usually., the current directory) — Docker sends the ENTIRE contents of that directory to the daemon BEFORE the build starts, even for files your Dockerfile never actually COPYs. - 02
This means a build context containing a
node_modulesfolder,.githistory, large log files, or test data gets uploaded to the daemon on EVERY build, even if your Dockerfile never references them — a real, measurable slowdown on large projects. - 03
A
.dockerignorefile (same syntax idea as.gitignore) EXCLUDES specified files/directories from the build context entirely — they're never sent to the daemon, never available to COPY, and never able to accidentally end up inside your image. - 04
Security angle: without a
.dockerignore, a stray.envfile with real secrets, or your.gitdirectory (which can contain the FULL history of every secret ever committed, even ones later 'removed'), can accidentally get copied into an image layer — and once baked into a layer, it's recoverable by anyone who can pull that image, EVEN IF a later layer 'deletes' the file (the earlier layer with the secret still exists in the image's history). - 05
A good baseline
.dockerignorefor almost any project: exclude.git,node_modules(ortarget/buildfor Java — you'llCOPYin only the specific built artifact, not the whole build directory),.env*files, and your ownDockerfile/.dockerignore(they don't need to be inside the image they define).
In your stack
- →
For a Maven/Gradle project, a
.dockerignoreshould excludetarget/orbuild/EXCEPT you typically still want toCOPYthe final built JAR from it — the common pattern is excluding the whole directory in.dockerignorefor a pre-built-JAR workflow, or letting a multi-stage build (Phase 7) compile fresh inside the container instead, sidestepping the question entirely.
Code & diagrams
A solid baseline for most Java/Spring Boot projects.
# Version control history — can contain old secrets, and you never need it in the image
.git
.gitignore
# Build output you'll rebuild fresh inside Docker, or copy in explicitly
target/
build/
# Local environment/secret files — NEVER let these enter an image layer
.env
.env.*
# IDE and OS cruft nobody needs inside a container
.idea/
.vscode/
.DS_Store
# The Docker files themselves don't need to be inside the image they define
Dockerfile
.dockerignore
docker-compose.yml
# Logs and local test artifacts
*.log
/logsExplain it without notes
Why can a secret still be recoverable from an image even if a LATER Dockerfile instruction deletes the file that contained it?
Why does a bloated build context slow down docker build even for files your Dockerfile never explicitly COPYs?
Practice
Create a project folder with a large dummy file (or a real node_modules if you have one) and NO .dockerignore, run docker build . and note the 'Sending build context to Docker daemon' size Docker prints. Add a .dockerignore excluding it and rebuild — compare the reported context size.
Deliberately COPY a fake '.env' file with a dummy secret into an image, then delete it in a later RUN instruction, then use docker history or docker save + extract to find whether the secret is still recoverable.
Trade-offs
- ↔
A thorough .dockerignore takes a few minutes to set up properly per project — a trivial cost against both meaningfully faster builds AND avoiding a genuine, recurring class of secret-leak security incidents.
Done when you can
Every project I containerize has a .dockerignore excluding .git, dependency folders, and secret files.
I understand that deleting a file in a later layer does not remove it from the image's history.
I've personally measured a build context size difference with and without .dockerignore.