Skip to content

Instantly share code, notes, and snippets.

@bartoszmajsak
Last active March 17, 2026 23:11
Show Gist options
  • Select an option

  • Save bartoszmajsak/acef582989d99f1f79f86984a63c3fc5 to your computer and use it in GitHub Desktop.

Select an option

Save bartoszmajsak/acef582989d99f1f79f86984a63c3fc5 to your computer and use it in GitHub Desktop.
Measure Docker build context size across legacy Docker, BuildKit, and Podman (with/without .dockerignore)
#!/usr/bin/env bash
# Measure Docker build context size with and without .dockerignore
# Covers: legacy Docker builder, BuildKit (via buildx), and Podman
#
# Run from the repo root where .dockerignore lives.
# The script temporarily moves .dockerignore aside to measure "without",
# then restores it to measure "with".
set -uo pipefail
DOCKERIGNORE=".dockerignore"
BACKUP=".dockerignore.bak"
MEASURE_DOCKERFILE=$(mktemp /tmp/ctx-measure.XXXXXX.Dockerfile)
trap 'rm -f "$MEASURE_DOCKERFILE"; [ -f "$BACKUP" ] && mv "$BACKUP" "$DOCKERIGNORE"' EXIT
cat > "$MEASURE_DOCKERFILE" <<'DEOF'
FROM busybox
COPY . /ctx
RUN du -sh /ctx
DEOF
without_dockerignore() {
[ -f "$DOCKERIGNORE" ] && mv "$DOCKERIGNORE" "$BACKUP"
}
with_dockerignore() {
[ -f "$BACKUP" ] && mv "$BACKUP" "$DOCKERIGNORE"
}
# Extract "1.5G /ctx" from BuildKit/Podman output where du is prefixed
# by build step metadata (e.g. "#7 0.315 1.5G /ctx" or bare "1.5G /ctx")
parse_du() {
grep -oE "[0-9][0-9.]*[KMGT][[:space:]]*/ctx" | head -1 || echo "(could not parse du output)"
}
# ---------- Legacy Docker builder ----------
echo "########## Legacy Docker builder (DOCKER_BUILDKIT=0) ##########"
echo ""
without_dockerignore
echo "--- Without .dockerignore ---"
DOCKER_BUILDKIT=0 docker build --no-cache -f - . <<< 'FROM scratch' 2>&1 \
| { grep "Sending build context" || echo "(no context size reported)"; }
with_dockerignore
echo "--- With .dockerignore ---"
DOCKER_BUILDKIT=0 docker build --no-cache -f - . <<< 'FROM scratch' 2>&1 \
| { grep "Sending build context" || echo "(no context size reported)"; }
echo ""
# ---------- BuildKit (via docker buildx) ----------
echo "########## BuildKit (docker buildx build --progress=plain) ##########"
echo ""
echo "Note: BuildKit does not print context size on its own."
echo "Using COPY . /ctx + du -sh to measure what arrives."
echo ""
without_dockerignore
echo "--- Without .dockerignore ---"
docker buildx build --progress=plain --no-cache -f "$MEASURE_DOCKERFILE" -t ctx-measure-bk . 2>&1 \
| parse_du
with_dockerignore
echo "--- With .dockerignore ---"
docker buildx build --progress=plain --no-cache -f "$MEASURE_DOCKERFILE" -t ctx-measure-bk . 2>&1 \
| parse_du
docker rmi ctx-measure-bk >/dev/null 2>&1 || true
echo ""
# ---------- Podman ----------
echo "########## Podman ##########"
echo ""
echo "Note: Podman does not report context size. Using COPY . /ctx + du -sh."
echo ""
without_dockerignore
echo "--- Without .dockerignore ---"
podman build --no-cache -f "$MEASURE_DOCKERFILE" -t ctx-measure-pm . 2>&1 \
| parse_du
with_dockerignore
echo "--- With .dockerignore ---"
podman build --no-cache -f "$MEASURE_DOCKERFILE" -t ctx-measure-pm . 2>&1 \
| parse_du
podman rmi ctx-measure-pm >/dev/null 2>&1 || true
@bartoszmajsak

Copy link
Copy Markdown
Author

Results on kserve/kserve repo

Context sizes

Builder Without .dockerignore With .dockerignore
Legacy Docker 1.572 GB 11.85 MB
BuildKit (buildx) 1.5 GB 11.9 MB
Podman 1.5 GB 11.9 MB

Where the 1.5 GB comes from

The Go Dockerfiles only need ~12 MB of source, but without an allowlist .dockerignore the entire repo gets sent as context:

Directory Size Needed by Go builds?
bin/ 452 MB No - compiled binaries
.git/ 373 MB No - VCS metadata
python/ 282 MB No - Python images use python/ as their own context
venv/ 190 MB No - local virtualenv
install/ 117 MB No - install manifests
hack/ 32 MB No - dev scripts
docs/ 30 MB No - documentation
test/ 20 MB No - test fixtures
pkg/ 6.7 MB Yes
tools/ 5.0 MB Yes
cmd/ 124 KB Yes
qpext/ 80 KB Yes
go.mod + go.sum 84 KB Yes
LICENSE 12 KB Yes

The allowlist .dockerignore includes only the last 6 rows, cutting context by 99.2%.

Note: BuildKit does not exclude .git/ automatically despite common belief - all three builders send the same ~1.5 GB without a .dockerignore.

@bartoszmajsak

bartoszmajsak commented Mar 17, 2026

Copy link
Copy Markdown
Author
########## Legacy Docker builder (DOCKER_BUILDKIT=0) ##########

--- Without .dockerignore ---
Sending build context to Docker daemon  1.572GB
--- With .dockerignore ---
Sending build context to Docker daemon  11.85MB

########## BuildKit (docker buildx build --progress=plain) ##########

Note: BuildKit does not print context size. Using COPY . /ctx + du -sh to measure what arrives.

--- Without .dockerignore ---
1.5G    /ctx
--- With .dockerignore ---
11.9M   /ctx

########## Podman ##########

Note: Podman does not report context size. Using COPY . /ctx + du -sh.

--- Without .dockerignore ---
1.5G    /ctx
--- With .dockerignore ---
11.9M   /ctx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment