CertGrid CertGrid
Hands-on Lab·Docker

Docker Build Context and .dockerignore

What the trailing dot in docker build actually sends, why a stray 3MB file made the image 6MB bigger, and how one .dockerignore file cut the transfer from 3.00MB to 138B. Measured both ways.

Dockerfiles and Builds Guide 16 of 46 Intermediate

Tested on the versions above. Transfer sizes depend on your own files. Step numbers and timings vary per run. Match the shape of the output, not the exact strings.

One Docker host is all this guide needs. Nothing here depends on a second machine, and the hardware above is modest on purpose - a 2 core, 4 GB VM runs everything in this path.
Server NameIP AddressOSRolesCPURAMHDD
DOCKER01192.168.0.21Ubuntu 26.04 LTSDocker Host2 Core4 GB50 GB

Before you start

  1. The dot is an argument, not punctuation

    In docker build -t name . the final dot is the build context: the directory handed to the builder. Instructions such as COPY can only read files from inside it, which is why copying something from outside the context is impossible rather than merely awkward.

    bash
    ls -la /tmp/cg-ctxtotal 3076drwxrwxr-x  3 sysadmin sysadmin     100 Aug 22 09:17 .drwxrwxrwt 13 root     root         260 Aug 22 09:17 ..-rw-rw-r--  1 sysadmin sysadmin      64 Aug 22 09:17 Dockerfile-rw-rw-r--  1 sysadmin sysadmin 3145728 Aug 22 09:17 bigfile.bindrwxrwxr-x  2 sysadmin sysadmin      60 Aug 22 09:17 src

    Expected resultA directory holding both what the build needs and what it does not.

    Success conditionYou can see at least one file the image has no use for. Real projects have many: .git, node_modules, test fixtures, local databases.

  2. Measure what actually transfers

    BuildKit reports the context transfer as a numbered step. This is worth watching, because the common advice that "the whole directory is uploaded" is only true when your instructions reference the whole directory. With COPY . . they do - and the full three megabytes moves.

    bash Example session
    docker build --no-cache -t cg-ctx:nodockerignore .#3 transferring context: 2B done#6 transferring context: 3.00MB done

    Expected resultTwo transfer lines - the small one is the .dockerignore lookup, the large one is the context itself.

    Success conditionYou can see the transferred size. Note it is reported per build, so this cost is paid every time.

  3. Add a .dockerignore

    The syntax is close to .gitignore: one pattern per line, matched against paths relative to the context root. It is read before anything transfers, which is why it reduces the transfer rather than merely the image.

    bash
    printf "bigfile.bin\n*.md\n" > .dockerignorecat .dockerignorebigfile.bin*.md

    Expected resultThe two patterns.

    Success conditionThe file is named exactly .dockerignore and sits at the context root - not next to the Dockerfile if those differ.

  4. Measure again

    Same Dockerfile, same command, same --no-cache. The only change is the ignore file, and the transfer drops by four orders of magnitude.

    bash Example session
    docker build --no-cache -t cg-ctx:withdockerignore .#3 transferring context: 57B done#6 transferring context: 138B done

    Expected resultThe context transfer falls from 3.00MB to 138B.

    Success conditionA dramatically smaller transfer. If it did not change, the pattern is not matching - patterns are relative to the context root, so a leading slash or a wrong directory prefix will silently match nothing.

  5. The image shrank too

    Because COPY . . copied the excluded file into the image as well, ignoring it removes it from both the transfer and the result. Six megabytes of image for a file nothing reads.

    bash Example session
    docker images --filter reference=cg-ctx --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}"REPOSITORY:TAG            SIZEcg-ctx:withdockerignore   12.8MBcg-ctx:nodockerignore     18.8MB

    Expected resultA 6MB difference from one ignore rule.

    Success conditionThe ignored build is smaller. On a real project with node_modules or .git the difference is usually far larger than this.

  6. Clean up

    Remove both tagged images and the working directory.

    bash
    # removes only what this guide builtdocker rmi cg-ctx:nodockerignore cg-ctx:withdockerignorerm -rf /tmp/cg-ctx# done

    Expected resultUntagged lines for both images.

    Success conditiondocker images --filter reference=cg-ctx returns nothing.

Troubleshooting

Official sources