Docker Build Context Analyzer

Find out what the pause labelled sending build context is actually sending. Paste the output of du -a . or find . -type f -printf '%s %p\n'.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Analyze. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

A repository with history and dependencies

Both uploaded on every build, and neither is needed in the image

200M	./.git
50M	./node_modules
5M	./src
1M	./package.json

A clean context

Still uploaded in full before the first instruction runs

4M	./src/app.js
1M	./src/vendor.js
1M	./package.json

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Leaving .git out of .dockerignore

    The entire repository history is uploaded on every build and is never used. It is usually the largest thing in the context.

    Instead:Add .git. It is the single highest-value line in that file.

  2. Blaming a slow build on the network or the registry

    The pause before the first instruction is the context upload, which happens locally and has nothing to do with either.

    Instead:Read what the context actually contains before optimising anything else.

  3. Building from a subdirectory to shrink the context

    The context is the path you pass, not the Dockerfile's location, so this changes nothing.

    Instead:Use .dockerignore, which is the only lever.

The whole context is transferred before the first instruction runs

Not the files a COPY needs: everything you passed as the build context. It happens on every build whether or not any of it is used.

.git is usually the largest single thing

The whole repository history, uploaded every build, and never needed inside the image. On a repository with any age it dominates the pause before anything appears to happen, and a single .dockerignore line removes it.

node_modules is slow and wrong

Slow to upload, and wrong to copy: a local install may hold binaries built for a different platform than the image, which then fail at run time with an architecture error rather than an obvious one. The install belongs inside the build, where it also caches properly.

BuildKit makes the second build cheaper, not the first

It transfers incrementally and caches between builds, so the full cost is paid once per builder and then only for what changed. On an ephemeral CI runner that means every job pays it in full.

A remote daemon pays more

Docker Desktop puts the daemon behind a VM boundary and a remote daemon puts it across a network, so the same context costs considerably more than it does with a local daemon on Linux.

Building from a subdirectory does not help

The context is what you pass on the command line, not what the Dockerfile reads. docker build -f sub/Dockerfile . still sends the whole current directory.

A .dockerignore is read before anything is sent

So the excluded files never leave your machine. It also stabilises the build cache, because a file that is not in the context cannot invalidate a COPY layer by changing.

More docker tools

Docker Container Image Reference Parser Is that a registry or a Docker Hub user? Dockerfile Linter What this image will do to you later docker run to Kubernetes YAML And the flags that have no equivalent Docker Compose to Kubernetes And why depends_on has no equivalent Docker Logging Driver Generator json-file never rotates Dockerfile Non-Root USER Generator Numeric, or Kubernetes rejects it Docker OCI Image Labels Generator One of them actually does something Docker Hub Pull Rate Limit Calculator Counted per IP, not per person Docker Registry Storage Calculator Deleting a tag frees nothing Docker Compose to docker run Converter Names stop resolving Docker Compose Version Migrator version: is obsolete now Docker Compose Network and Port Viewer Everything reaches everything Docker Command Explainer Which flags hand over the host Docker BuildKit Cache Mount Generator apt deletes the cache you just mounted Docker BuildKit Secret Mount Generator ARG is in docker history forever Docker .dockerignore Pattern Tester *.log does not match logs/app.log Docker Image Manifest Viewer unknown/unknown is not broken Docker Image Config Viewer Anyone who can pull can read your Env Docker Registry Token Decoder Check the scope before the credentials Docker HEALTHCHECK Generator Docker does nothing when it fails Docker Network Subnet Calculator 31 networks, then it stops Docker History Analyzer The rm did not save anything Docker Run to Compose Converter Some flags have no equivalent Docker CMD and ENTRYPOINT Tester Why docker stop takes ten seconds Docker Port Mapping Tester -p reaches past your firewall Docker -v to --mount Converter -v invents missing directories Docker Restart Policy Simulator The backoff resets after ten seconds Docker Exit Code Explainer 137 is two different problems Docker CPU Limit Converter --cpu-shares limits nothing Docker Memory Limit Calculator -m 512m allows a gigabyte Docker Compose Interpolation Tester An unset variable is an empty string Docker Environment Variable Precedence Tester Your shell does not reach the container Docker Compose Override Merge Previewer An override can add a port, never remove one Dockerfile Multi-Stage Build Analyzer Which stages reach the image Dockerignore Validator It is not .gitignore

Elsewhere on the site