Docker Context — What Gets Sent to the Daemon During Build
What Is the Docker Build Context in Simple Terms?
When you run docker build ., the . is the build context — it tells Docker which directory to use as the source of files for the build. Docker reads everything in that directory (except what is in .dockerignore) and sends the entire content to the Docker daemon before a single Dockerfile instruction is executed.
This means if your project directory contains a node_modules folder with 500MB of packages, Docker sends 500MB to the daemon even if you never use those files in the Dockerfile. A large build context is one of the most common causes of slow Docker builds.
+------------------------------------------+| Your project directory (build context) || || /src/ <- your source code || /node_modules/<- 500MB of packages || /.git/ <- git history || /tests/ <- test files || /.env <- secrets! |+------------------------------------------+ | | docker build . | Sends EVERYTHING to daemon v+------------------------------------------+| Docker Daemon || Receives entire context (1.2GB) || Then starts executing Dockerfile |+------------------------------------------+ With .dockerignore:+------------------------------------------+| /src/ <- your source code |+------------------------------------------+ | | docker build . | Sends only what is not ignored (2MB) v+------------------------------------------+| Docker Daemon receives 2MB not 1.2GB || Build starts in seconds not minutes |+------------------------------------------+Measuring Build Context Size
# The first line of docker build output shows context sizedocker build .# Sending build context to Docker daemon 1.2GB# <- 1.2GB sent before a single instruction runs # With .dockerignore:docker build .# Sending build context to Docker daemon 2.3MB# <- 2.3MB — 520x reduction # Why context size matters:# 1.2GB context on a local network: ~5-10 seconds# 1.2GB context on remote build server: 30-60 seconds# 2.3MB context: < 1 second in either caseThe .dockerignore File
# .dockerignore — same syntax as .gitignore # Node.jsnode_modules/npm-debug.log.npm/.yarn/ # Build output (built inside container, not copied from host)dist/build/.next/out/ # Version control.git/.gitignore.gitattributes # Environment files — NEVER copy secrets into images.env.env.*!.env.example # Development tools.vscode/.idea/*.swp*.swo # Testscoverage/.nyc_output/__tests__/*.test.ts*.spec.ts*.test.js*.spec.js # Docker filesDockerfileDockerfile.*docker-compose.ymldocker-compose.*.yml # Documentationdocs/*.mdREADME.md # macOS.DS_Store # Python__pycache__/*.pyc*.pyo.pytest_cache/venv/.venv/Using a Different Build Context
# Use current directory as context (most common)docker build . # Use a specific directory as contextdocker build /path/to/project # Use a different Dockerfile with same contextdocker build -f Dockerfile.prod . # Use a different Dockerfile AND different contextdocker build -f /path/to/Dockerfile /path/to/context # Build from a Git URL (context is the repository)docker build https://github.com/myorg/myrepo.git#main# Docker clones the repo and uses it as the build context# Useful for building without needing the code locally # Build from stdin (no context — no COPY instructions possible)docker build - < Dockerfile# orcat Dockerfile | docker build -Context vs .dockerignore vs COPY
Three levels of file inclusion: 1. Build context — what directory docker build uses (controlled by the path argument in docker build .) 2. .dockerignore — which files WITHIN context are excluded (reduces what is sent to the daemon) 3. COPY instruction — which files from context go INTO the image (controls which context files end up in a layer) Example:Project has: src/, tests/, node_modules/, .env .dockerignore excludes: node_modules/, .env, tests/Context sent to daemon: src/ only Dockerfile: COPY src/ /app/src/ <- copies src into image COPY . . <- would copy only src/ (tests/ excluded by .dockerignore)Troubleshooting Reference
| Problem | Cause | Fix |
|---|---|---|
| Build very slow even with cached layers | Large build context | Add .dockerignore to exclude node_modules, .git, build artifacts |
COPY . . copies unwanted files |
No .dockerignore |
Create .dockerignore with exclusions |
| Secrets accidentally in image | .env not in .dockerignore |
Add .env* to .dockerignore and rebuild |
COPY fails with not found |
File excluded by .dockerignore |
Remove exclusion or use specific COPY instead of COPY . . |
PLACEMENT PRO TIP**Tip:** Create a `.dockerignore` file as the very first thing in every new project — before you write a single Dockerfile instruction. It is much easier to add it at the start than to debug why your builds are slow or why secrets ended up in an image layer six months later.
COMMON MISTAKE / WARNING**Common Mistake:** Thinking that `.dockerignore` controls what ends up in the image. It does not — it controls what is sent to the daemon. To control what ends up in an image layer, use specific `COPY src/ /app/src/` instructions instead of `COPY . .`. Both are needed for a correct setup: `.dockerignore` for build speed, specific COPY for image content.