As is the case with the Docker's best practices for Dockerfiles in the official documentation, they're leaving out some really important details.<p>Specifically, they don't really express how Docker packaging is a process integrating the way you build, where you build, and how you build, not just the Dockerfile.<p>1. Caching is great... but it can also lead to insecure images because you don't get system package updates if you're only ever building off a cached image. Solution: rebuild once a week from scratch. (<a href="https://pythonspeed.com/articles/docker-cache-insecure-images/" rel="nofollow">https://pythonspeed.com/articles/docker-cache-insecure-image...</a>)<p>2. Multi-stage builds give you smaller images, but if you don't use them right they result in breaking caching completely, destroying all the speed and size benefits you get from layer caching. Solution: you need to tag and push the build-stage images too, and then pull them before the build, if you want caching to work. (Long version, this is a bit tricky to get right: <a href="https://pythonspeed.com/articles/faster-multi-stage-builds/" rel="nofollow">https://pythonspeed.com/articles/faster-multi-stage-builds/</a>)