CodeRigor

FREE LESSON

Build context, Dockerfiles and reusable layers

Select build inputs by path boundaries and model why an early changed instruction invalidates a sequential cache suffix.

docker build -f packaging/Dockerfile . names two things: a recipe and a context. The final dot selects the directory whose files the builder may use. Choosing a different Dockerfile location does not automatically restrict that context to the Dockerfile's directory. Start every packaging review by identifying both inputs, especially when the working tree contains credentials, datasets or editor state.

Our lab receives a file mapping rather than accessing a real directory. It applies a deliberately small exact-path/subtree exclusion rule. Actual .dockerignore has its own patterns, negation and ordering rules; the Python helper does not implement that language. A correct fixture answer is evidence about this contract, not proof that an arbitrary ignore file protects a real build.

A build receives a selected context
start / 2
Context selection precedes COPY. A later deletion cannot undo an earlier disclosure.
A build receives a selected context
Context selection precedes COPY. A later deletion cannot undo an earlier disclosure.

Read the recipe as an ordered construction

A small standard-library service needs no package installation:

Dockerfile
FROM python:3.14-slim
WORKDIR /app
RUN mkdir -p /data && chown 10001:10001 /data
COPY ["service.py", "healthcheck.py", "/app/"]
USER 10001:10001
EXPOSE 8000
ENTRYPOINT ["python", "/app/service.py"]
CMD ["--data-dir", "/data"]

FROM selects a base; WORKDIR sets the working directory; COPY contributes selected source files. USER, port metadata and command arrays configure the resulting image. Some instructions primarily affect metadata rather than adding application filesystem bytes, so “one Dockerfile line equals one new data layer” is an unreliable rule. A mutable tag can later resolve to different base contents. A digest can pin a selected base, while updates still require deliberate review.

Keep frequently changing source copies after expensive dependency installation in applications that need it. That ordering can preserve earlier reusable work. It does not justify caching secrets, skipping necessary dependency updates or copying the entire repository without examining what it contains.

Reuse is a leading-prefix decision
start / 2
These strings stand for instruction-plus-input fingerprints, not real Docker cache keys.
Reuse is a leading-prefix decision
These strings stand for instruction-plus-input fingerprints, not real Docker cache keys.

Model just enough cache dependency

The cache exercise accepts already-computed fingerprints. It counts matching leading steps, then stops. It never computes a real BuildKit key or claims to model its dependency graph. This linear approximation exposes one useful dependency: a changed parent means a later identical-looking command cannot simply reuse the previous result on that parent.

Python
before = ["base:A", "deps:D", "source:old", "test:T"]
after = ["base:A", "deps:D", "source:new", "test:T"]
reused = 0
for old, new in zip(before, after):
    if old != new:
        break
    reused += 1
print(reused)

Match directories on component boundaries

An exclusion secrets covers secrets and secrets/key, but leaves secrets-old/readme alone. A raw startswith("secrets") test erases that distinction. Validate canonical relative paths first, then compare equality or prefix-plus-slash. Reject traversal and malformed paths even when a file would be excluded; bad inputs should not become valid merely because another rule hides them.

The build combines context selection with cache-prefix accounting. The bug hunts target over-broad exclusion and continuing after a cache mismatch. For transfer practice, compare the supplied project's .dockerignore to this model and list features it uses that the model cannot express. Removing a copied secret in a later instruction is not a reliable way to remove it from earlier image history; prevent the secret from entering the context or use the appropriate build-secret facility.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

Watch the image-build demonstration. Identify the Dockerfile, source directory and resulting image; use this lesson and the official context reference for cache and ignore-file details.