4

Some security updates have just come out and I want to rebuild my Docker images to take advantage of the updates.

However when I run docker build . it completes immediately without updating anything because nothing has changed in the Dockerfile, and everything is cached. It doesn't even try to run the apt-get update line in my Dockerfile.

How can I force Docker to run the apt-get update command again, even though nothing has changed?

There is a --no-cache option that says it won't use the cache during the build, but I want it to use the cache for the commands before apt-get update and I want the results saved into the cache for the next run (replacing the currently cached images), so I definitely want to be using the cache.

I also can't use docker rmi to remove the image generated at the point after apt-get has been run, because it refuses to delete this image as the image has dependent child images.

  • You can use --no-cache option – ALex_hha Mar 7 '18 at 13:18
  • @ALex_hha: But I want to use the cache – Malvineous Mar 7 '18 at 14:00
  • What do you mean? If you need to rebuild the image - you won't be able to use cache – ALex_hha Mar 7 '18 at 15:22
  • Like I said in the question, I want to use the cache for the commands that run before apt-get does, and I want the results of each step saved into the cache for future runs. --no-cache will cause every single step to run again, whereas I only want apt-get and the following steps to be re-run. – Malvineous Mar 8 '18 at 3:13
5

You can try something like the following:

FROM ubuntu:16.04

# LAYER 1
RUN echo "$(date), layer1" > /tmp/cache.txt

# LAYER 2
RUN echo "$(date), layer2" >> /tmp/cache.txt

# LAYER 3
ARG FORCE_UPDATE=no
RUN echo "$(date), layer3" >> /tmp/cache.txt

# LAYER 4
RUN echo "$(date), layer4" >> /tmp/cache.txt

CMD ["cat", "/tmp/cache.txt"]

Build image for the first time

$ docker build -t serverfault:900445 .
Sending build context to Docker daemon  2.048kB
Step 1/7 : FROM ubuntu:16.04
 ---> 0458a4468cbc
Step 2/7 : RUN echo "$(date), layer1" > /tmp/cache.txt
 ---> Running in ac7f6b1e915a
Removing intermediate container ac7f6b1e915a
 ---> 42a6d14cc4cc
Step 3/7 : RUN echo "$(date), layer2" >> /tmp/cache.txt
 ---> Running in ba4cf5b54c35
Removing intermediate container ba4cf5b54c35
 ---> 783957979b21
Step 4/7 : ARG FORCE_UPDATE=no
 ---> Running in 818fd652d5cb
Removing intermediate container 818fd652d5cb
 ---> b8afb473cd9d
Step 5/7 : RUN echo "$(date), layer3" >> /tmp/cache.txt
 ---> Running in 38c0e6cbb94e
Removing intermediate container 38c0e6cbb94e
 ---> 03ac41df5bfa
Step 6/7 : RUN echo "$(date), layer4" >> /tmp/cache.txt
 ---> Running in 0294b5a4078e
Removing intermediate container 0294b5a4078e
 ---> 141667a2d5f3
Step 7/7 : CMD ["cat", "/tmp/cache.txt"]
 ---> Running in 86b852d8222d
Removing intermediate container 86b852d8222d
 ---> dcd57aca0c25
Successfully built dcd57aca0c25
Successfully tagged serverfault:900445

As we can see all layers were built. Run one more time

$ docker build -t serverfault:900445 .
Sending build context to Docker daemon  2.048kB
Step 1/7 : FROM ubuntu:16.04
 ---> 0458a4468cbc
Step 2/7 : RUN echo "$(date), layer1" > /tmp/cache.txt
 ---> Using cache
 ---> 42a6d14cc4cc
Step 3/7 : RUN echo "$(date), layer2" >> /tmp/cache.txt
 ---> Using cache
 ---> 783957979b21
Step 4/7 : ARG FORCE_UPDATE=no
 ---> Using cache
 ---> b8afb473cd9d
Step 5/7 : RUN echo "$(date), layer3" >> /tmp/cache.txt
 ---> Using cache
 ---> 03ac41df5bfa
Step 6/7 : RUN echo "$(date), layer4" >> /tmp/cache.txt
 ---> Using cache
 ---> 141667a2d5f3
Step 7/7 : CMD ["cat", "/tmp/cache.txt"]
 ---> Using cache
 ---> dcd57aca0c25
Successfully built dcd57aca0c25
Successfully tagged serverfault:900445

And now all layers were taken from cache. Simple check

$ docker run -it --rm serverfault:900445
Wed Mar  7 15:44:22 UTC 2018, layer1
Wed Mar  7 15:44:23 UTC 2018, layer2
Wed Mar  7 15:44:24 UTC 2018, layer3
Wed Mar  7 15:44:25 UTC 2018, layer4

Now if you need to force update cache for some specific layer use the following

$ docker build --build-arg FORCE_UPDATE=$(date '+%s') -t serverfault:900445 .
Sending build context to Docker daemon  2.048kB
Step 1/7 : FROM ubuntu:16.04
 ---> 0458a4468cbc
Step 2/7 : RUN echo "$(date), layer1" > /tmp/cache.txt
 ---> Using cache
 ---> 42a6d14cc4cc
Step 3/7 : RUN echo "$(date), layer2" >> /tmp/cache.txt
 ---> Using cache
 ---> 783957979b21
Step 4/7 : ARG FORCE_UPDATE=no
 ---> Using cache
 ---> b8afb473cd9d
Step 5/7 : RUN echo "$(date), layer3" >> /tmp/cache.txt
 ---> Running in f8ad1cd195eb
Removing intermediate container f8ad1cd195eb
 ---> b22972691095
Step 6/7 : RUN echo "$(date), layer4" >> /tmp/cache.txt
 ---> Running in 9994175a082e
Removing intermediate container 9994175a082e
 ---> 7ed42904373f
Step 7/7 : CMD ["cat", "/tmp/cache.txt"]
 ---> Running in 67de76e45d43
Removing intermediate container 67de76e45d43
 ---> 833f3faf9fd7
Successfully built 833f3faf9fd7
Successfully tagged serverfault:900445

As you can see layers 1,2 were taken from cache but layer 3 and all latest layers were rebuilt

$ docker run -it --rm serverfault:900445
Wed Mar  7 15:44:22 UTC 2018, layer1
Wed Mar  7 15:44:23 UTC 2018, layer2
Wed Mar  7 15:45:35 UTC 2018, layer3
Wed Mar  7 15:45:35 UTC 2018, layer4

Repeat one more time

$ docker build --build-arg FORCE_UPDATE=$(date '+%s') -t serverfault:900445 .
Sending build context to Docker daemon  2.048kB
Step 1/7 : FROM ubuntu:16.04
 ---> 0458a4468cbc
Step 2/7 : RUN echo "$(date), layer1" > /tmp/cache.txt
 ---> Using cache
 ---> 42a6d14cc4cc
Step 3/7 : RUN echo "$(date), layer2" >> /tmp/cache.txt
 ---> Using cache
 ---> 783957979b21
Step 4/7 : ARG FORCE_UPDATE=no
 ---> Using cache
 ---> b8afb473cd9d
Step 5/7 : RUN echo "$(date), layer3" >> /tmp/cache.txt
 ---> Running in 618880ba45be
Removing intermediate container 618880ba45be
 ---> b0512372ddfd
Step 6/7 : RUN echo "$(date), layer4" >> /tmp/cache.txt
 ---> Running in 0cb552431048
Removing intermediate container 0cb552431048
 ---> 61be6f0c0f21
Step 7/7 : CMD ["cat", "/tmp/cache.txt"]
 ---> Running in 5f9ee850c28e
Removing intermediate container 5f9ee850c28e
 ---> ac73b7754107
Successfully built ac73b7754107
Successfully tagged serverfault:900445


$ docker run -it --rm serverfault:900445
Wed Mar  7 15:44:22 UTC 2018, layer1
Wed Mar  7 15:44:23 UTC 2018, layer2
Wed Mar  7 15:46:10 UTC 2018, layer3
Wed Mar  7 15:46:11 UTC 2018, layer4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.