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
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'.
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.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
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.
Both uploaded on every build, and neither is needed in the image
200M ./.git 50M ./node_modules 5M ./src 1M ./package.json
Still uploaded in full before the first instruction runs
4M ./src/app.js 1M ./src/vendor.js 1M ./package.json
These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
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.
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.
The context is the path you pass, not the Dockerfile's location, so this changes nothing.
Instead:Use .dockerignore, which is the only lever.
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.
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.
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.
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.
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.
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.
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.