2

I have the following dockerfile:

FROM debian:buster

#Configure apt to look at my Debian repository
COPY ./apt /etc/apt

#Install the software into the image

RUN apt-get update && apt-get -V -y dist-upgrade && apt-get -V -y --allow-unauthenticated --no-install-recommends --allow-downgrades install -f business=1.1-0

ENTRYPOINT ["/usr/sbin/main.sh"]
CMD []

So basically it installs package “business” from version 1.1-0 I have a problem with docker cache, I’m pushing a new code change of package “business” with the same version (1.1-0) [yes I’m overriding versions…] and docker cache is not smart enough to pull the new changed .deb.

It uses the cached layer without my code change :frowning: As workaround, I build with --no-cache but I don’t like this solution because I’m losing the caching mechanism.

Any way to solve that? Can I build with no cache only from specific layer?

  • Docker's layer caching is based on the text of the `RUN` command; if a previous run has already installed `business=1.1-0` and that `RUN` line hasn't changed then Docker will in fact reuse the previous version. Can you use a different version number for the package in each build, or `COPY` the `.deb` file into the image and then `RUN dpkg --install` it? – David Maze Mar 01 '23 at 14:31
  • This is a good suggestion but I think for now i'll continue to use apt with `--no-cache`. is the 'textual check' relevant only for "RUN" layers? as I know COPY checks for file's checksums – Barel Elbaz Mar 02 '23 at 12:43
  • I believe the "it is the same text" check applies to all commands, and `COPY` (and `ADD`) additionally hash the file contents. – David Maze Mar 02 '23 at 14:34

1 Answers1

5

Yes you can,

option a)

  • split your dockerfile , generate a random result in the uncached command:
    RUN apt-get update && apt-get -V -y dist-upgrade 
    RUN head -c 23 /dev/urandom > /.randfile  && apt-get -V -y --allow-unauthenticated --no-install-recommends --allow-downgrades install -f business=1.1-0
    

option b)

  • use multi-staged builds , but generate the second image with the --no-cache option of docker-compose and docker build ( e.g. do the upgrades in a first pipeline , push as someimage:baseimage, then use FROM someimage:baseimage in the next stage

option c)

  • 2
    The ideal type of answer that I expected to get is about making docker cache more smarter and figure out if the binary itself was changed but the version wasn't but it's seems to be impossible and wanted/in-purpose behavior of Docker (There is an assumption that versions are not overwritten and there is no chance to validate the binary without downloading it) so I'll accept your answer :-) – Barel Elbaz Mar 02 '23 at 12:41