We have a Dockerfile, where at a certain point would like no caching to happen.
Currently we are using
ENV CACHE_BUST=$($RANDOM)
Upon further inspection, funny enough that gets cached:
Step 1/1 : ENV CACHE_BUST=$($RANDOM)
---> Using cache
Is there any way from inside the Dockerfile to bust the cache without passing in a unique build-arg
(Like docker build . --build-arg CACHE_BUST=$(date +%s)
) in the build step?
If you want to pass multiple build arguments with docker build command you have to pass each argument with separate — build-arg. docker build -t <image-name>:<tag> --build-arg <key1>=<value1> --build-arg <key2>=<value2> .
Docker Build Cache The concept of Docker images comes with immutable layers. Every command you execute results in a new layer that contains the changes compared to the previous layer. All previously built layers are cached and can be reused.
You have to use two combinations, one after the other: ctrl+p followed by ctrl+q. You turn interactive mode to daemon mode, which keeps the container running but frees up your terminal. You can attach to it later using docker attach, if you need to interact with the container more.
Differences between CMD & ENTRYPOINT CMD commands are ignored by Daemon when there are parameters stated within the docker run command while ENTRYPOINT instructions are not ignored but instead are appended as command line parameters by treating those as arguments of the command.
Update: Reviewing this one, it looks like you injected the cache busting option incorrectly in two ways:
ENV
is not an ARG
$(x)
syntax is not a variable expansion, you need curly brackets (${}
), not parenthesis ($()
).To break the cache on the next run line, the syntax is:
ARG CACHE_BUST
RUN echo "command with external dependencies"
And then build with:
docker build --build-arg CACHE_BUST=$(date +%s) .
Why does that work? Because during the build, the values for ARG
are injected into RUN
commands as environment variables. Changing an environment variable results in a cache miss on the new build.
To bust the cache, one of the inputs needs to change. If the command being run is the same, the cache will be reused even if the command has external dependencies that have changed, since docker cannot see those external dependencies.
Options to work around this include:
--no-cache
option.Since you do not want to do option 1, there is a way to do option 3 on a specific line, but only if you can split up your Dockerfile into 2 parts. The first Dockerfile has all the lines as you have today up to the point you want to break the cache. Then the second Dockerfile has a FROM line to depend on the first Dockerfile, and you build that with the --no-cache
option. E.g.
Dockerfile1:
FROM base
RUN normal steps
Dockerfile2
FROM intermediate
RUN curl external.jar>file.jar
RUN other lines that cannot be cached
CMD your cmd
Then build with:
docker build -f Dockerfile1 -t intermediate .
docker build -f Dockerfile2 -t final --no-cache .
The only other option I can think of is to make a new frontend with BuildKit that allows you to inject an explicit cache break, or unique variable that results in a cache break.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With