https://docs.docker.com/engine/reference/commandline/build/#...
The downside of trying to jam all of your commands into a gigantic single RUN invocation is that if it isn't correct/you need to troubleshoot it, you can wind up waiting 10-20 minutes between each single line change just waiting for your build to finish.
You lose all the layer caching benefits and it has to re-do the entire build.
Just a heads up for anyone that's not suffered through this before.
I’m confused why they haven’t implemented a COMMIT instruction.
It’s so common to have people chain “command && command && command && command” to group things into a single layer. Surely it would be better to put something like “AUTOCOMMIT off” at the start of the Dockerfile and then “COMMIT” whenever you want to explicitly close the current layer. It seems much simpler than everybody hacking around it with shell side-effects.
> "--squash" is only supported on a Docker daemon with experimental features enabled
Up til now, our biggest improvement was with "FROM SCRATCH".
> Others should note it's still experimental and your build command may fail with
You might try "docker buildx build", to use the BuildKit client -- squash isn't experimental in that one I believe =)https://docs.docker.com/engine/reference/commandline/buildx_...
Thanks for the tip!
RUN ./setup.sh
I have seen that in some cases as a way to reduce layer count while avoiding complex hard to read RUN commands. Also seen it as a way to share common setup across multiple Docker images: RUN ./common_setup_for_all_images.sh
RUN ./custom_setup_for_this_image.sh
However this approach of doing most of the work in scripts does not seem common, so I'm wondering if there is a downside to doing that.As a concrete example... if your setup.sh were:
#!/bin/bash
./update_static_assets.sh
./install_libraries.sh
./clone_application_repo.sh
then any time a static asset is updated, a library is changed, or your application code changes, the digest of the Docker layer for `RUN ./setup.sh` will change. Your team will then have to re-download the result of all three of those sub-scripts next time they `docker pull`.However, if you found that static assets changed less often than libraries, which changed less often than your application code, then splitting setup.sh into three correspondingly-ordered `RUN` statements would put the result of each sub-script its own layer. Then, if just your application code changed, you and your team wouldn't need to re-download the library and static asset layers.
Personally I would not merge steps, which have nothing to do with each other, unless I am sure, that they are basically set in stone forever.
With public and widely popular base images, which are not changed once they are released, the choices might be weighed differently, as all the people, who make use of your image, will want to have fast download and small resulting images building on top of it.
Simply put: Don't make your development more annoying than necessary, by unnecessarily introducing long wait times for building docker images.
This creates two image layers - the first layer has all the added foo, including any intermediate artifacts. Then the second layer removes the intermediate artifacts, but that's saved as a diff against the previous layer:
Instead, you need to do them in the same RUN command: This creates a single layer which has only the foo artifacts you need.This why the official Dockerfile best practices show[1] the apt cache being cleaned up in the same RUN command:
[1] https://docs.docker.com/develop/develop-images/dockerfile_be...