When you execute the Docker pull command or Docker run command, the daemon first checks for a similar image in the local machine by comparing the digests of the image.
If it finds a match, then it’s not required to search the registry for the image and the daemon can simply create a copy of the already existing image. However, if a copy is not found, it starts pulling it from the registry. The same is the case when you try to build images using a Dockerfile.
We all know that Docker images are multi-layered files containing multiple image layers on top of each other. Each instruction mentioned inside a Dockerfile is responsible for creating a new layer.
A layer only consists of the differences between the previous layer and the current layer. If you have previously built the same image, the daemon will look for a cache containing the same image layer. If a subsequent cache is found, it will simply use this cache and not build a new layer.
However, there might be situations where you want to force a clean build of the image even if the build cache of subsequent layers exists. Here too, Docker has got your back. Let’s see how you can force clean build a Docker image.
Consider the Dockerfile below.
RUN apt-get update RUN apt-get -y install vim
In the above Dockerfile, we have used two different RUN instructions in separate lines. This results in the build of separate image layers and build caches. When the Docker daemon processes an update command such as RUN apt-get -y update, those packages inside the container on which the update commands work are not compared to determine if a cache hit takes place or not. In such a case, only the command string is compared to find the match.
Instead of using two separate lines for two consecutive RUN instructions, you can chain them to reduce the number of image layers and hence, reducing the possibility of a cache hit.
RUN apt-get update && apt-get -y install vim
If you don’t want to allow the daemon to perform checks for cache at all, you can use the --no-cache option to do so. When you use the Docker build command to build a Docker image, you can simply use the --no-cache option which will allow you to instruct daemon to not look for already existing image layers and simply force clean build of an image.
For example, if you want to build an image from the following Dockerfile -
FROM ubuntu:latest WORKDIR /app COPY . . MAINTAINER email@example.com RUN apt-get -y update RUN apt-get install -y openjdk-7-jdk RUN apt-get install -y git-core RUN apt-get install -y build-essential RUN apt-get install -y lsb-release CMD ["javac", "sample.java"]
Suppose you have already built this image previously and you have now made some changes in the build context. Hence, the COPY instruction cache breaks and so does the cache of all the subsequent instructions. If you have not made any changes and have built the image once again, there is no cache break and the daemon simply uses the existing cache of the image layers to build the image.
This is the default behavior and if you want to override this default behavior, you can use the --no-cache option along with the Docker build command.
$ docker build --no-cache -t sample-image:sample-tag .
When you execute this command, the daemon will not look for cache builds of existing image layers and will force a clean build of the Docker image from the Dockerfile.
If you use Docker compose, you can use the following command.
$ docker-compose build --no-cache
You can also chain this with the up command to recreate all containers.
$ docker-compose build --no-cache && docker-compose up -d --force-recreate
Please note that these ways do not use the cache but the builder and the base images are referenced using the FROM instruction. You can clean the builder cache using -
$ docker builder prune -af
You can also clear the parent images if you don’t want to use it’s cache.
$ docker image rm -f parent-image
These were the most common approaches that you can adopt to force clean an image build and to avoid using the image layer caches. The best and probably the easiest option is to use the --no-cache option.