Command Palette

Search for a command to run...

Hectal
PHASE 2Beginner ~13 min· topic 3 of 5

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.

0/5 · 0%

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

  1. 01

    The BUILD CONTEXT is the directory you point docker build at (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.

  2. 02

    This means a build context containing a node_modules folder, .git history, 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.

  3. 03

    A .dockerignore file (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.

  4. 04

    Security angle: without a .dockerignore, a stray .env file with real secrets, or your .git directory (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).

  5. 05

    A good baseline .dockerignore for almost any project: exclude .git, node_modules (or target/build for Java — you'll COPY in only the specific built artifact, not the whole build directory), .env* files, and your own Dockerfile/.dockerignore (they don't need to be inside the image they define).

In your stack

  • →

    For a Maven/Gradle project, a .dockerignore should exclude target/ or build/ EXCEPT you typically still want to COPY the final built JAR from it — the common pattern is excluding the whole directory in .dockerignore for 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

.dockerignoremarkdown

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
/logs

Explain it without notes

01

Why can a secret still be recoverable from an image even if a LATER Dockerfile instruction deletes the file that contained it?

02

Why does a bloated build context slow down docker build even for files your Dockerfile never explicitly COPYs?

Practice

01

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.

02

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.