@@ -331,3 +331,36 @@ No behavior change, and the id survives environments that cannot resolve
331331container-internal user names. (The `apk add` here stays unpinned under the
332332DL3018 ignore above — that is the scoped exception in action, not a
333333contradiction of it.)
334+
335+ # # Pattern 10: Validating a change to a custom base image needs the real image, not a stand-in
336+
337+ SKILL.md's "Mock upstream DNS" gotcha (`docker run --add-host backend:127.0.0.1
338+ nginx-image nginx -t`) assumes `nginx-image` really is the image under test.
339+ When the change under test lives in a *shared/base* image maintained
340+ elsewhere — one that compiles in extra modules or ships modified system
341+ files — substituting a generic public image of the same software (e.g.
342+ ` nginx:alpine` in place of a custom nginx+PHP-FPM base image) produces
343+ unrelated, misleading errors instead of testing the actual change :
344+
345+ ` ` `
346+ $ docker run --rm -v $PWD/rootfs/etc/nginx:/etc/nginx:ro nginx:alpine nginx -t
347+ nginx: [emerg] getpwnam("www-data") failed # base has no www-data user
348+ ...
349+ nginx: [emerg] open() "/etc/nginx/mime.types" failed # base ships mime.types elsewhere
350+ ...
351+ nginx: [emerg] unknown directive "brotli" # real image compiles brotli in, nginx:alpine doesn't
352+ ` ` `
353+
354+ None of these are about the change under test — they're artifacts of the
355+ wrong base. Build or pull the actual image first, then run the check against
356+ it :
357+
358+ ` ` ` bash
359+ docker build --build-arg PHP_VERSION=84 -t custom-image:test .
360+ docker run --rm --add-host phpfpm:127.0.0.1 --entrypoint sh custom-image:test -c "nginx -t"
361+ ` ` `
362+
363+ This costs one build (or pull, if the base is already published and registry
364+ auth is already configured), not a rewrite of the stand-in's `/etc/nginx` to
365+ patch in the missing pieces — that arms race never converges once the real
366+ base changes again.
0 commit comments