Deployment & Infra
Image layers: multiple-choice review
Six questions that cut across the whole unit. Each one mirrors a decision you make while writing or reviewing a real Dockerfile — not a definition to recite, but a cache-and-image tradeoff to reason through.
Confirm you can connect the cache-prefix model, instruction ordering, multi-stage builds, base-image choice, build-context hygiene, and the immutable-layer secret trap — the synthesis the lesson built toward.
A teammate moves RUN npm ci to sit just before the final CMD, reasoning that 'install is expensive so it should run last.' What actually happens to cache behaviour on a routine source edit?
A Dockerfile has these two lines as separate instructions. Builds keep installing months-old package versions even after the upstream repo updated. Why? RUN apt-get update RUN apt-get install -y curl
A single-stage Go build ships a ~180 MB image. A teammate proposes appending 'RUN apt-get remove -y build-essential && rm -rf /usr/local/go' at the end to slim it. Will the image shrink?
You need the smallest, most hardened production image for a self-contained compiled service, and CVE-scan noise must be near zero. Which final-stage base is the senior default, and what cost do you accept?
During CI a build needs a private-registry token to fetch dependencies. An engineer writes COPY token.txt /tmp/token, uses it in a RUN, then RUN rm /tmp/token in the next instruction. The final image is published. What is the exposure?
docker build is slow to even start — several seconds elapse before the first instruction runs — and COPY . . occasionally pulls a developer's local .env into the image. The repo has no .dockerignore. What single change addresses both?
The through-line is one model: an image is immutable stacked layers, the cache is a strict prefix, and RUN is keyed on command text rather than effect. Order least- to most-changing so the expensive install stays a cache hit; merge update-and-install so they invalidate together; multi-stage so you compile fat and ship slim instead of deleting bytes that never leave history; pick distroless when you want minimal attack surface and accept losing the shell; and keep the build context lean with .dockerignore. The hardest trap — a secret added then rm’d — falls out of the same immutability rule: you cannot delete it back out, so it must never become a layer.