How to Make Docker Rebuild an Image Without Its Cache

0

Docker caches image build results to accelerate subsequent rebuilds. While this mechanism is generally reliable, sometimes you’ll want to rebuild an image without using the cache. This could be to diagnose issues or check the complete build procedure will be reproducible in a clean environment.

In this article, you’ll learn how to achieve a fresh build without manually deleting the cache. You’ll also see how to pull updated base images so your build matches the output that a new Docker installation would produce.

How the Cache Works

Here’s a simple Dockerfile:

FROM alpine:latest
COPY 1.txt /1.txt
COPY 2.txt /2.txt

Populate the sample files in your working directory and build the image:

$ echo 1 > 1.txt
$ echo 2 > 2.txt
$ docker build -t demo:latest .

The output will look similar to this:

Sending build context to Docker daemon   5.12kB
Step 1/3 : FROM alpine:latest
 ---> 9c6f07244728
Step 2/3 : COPY 1.txt /1.txt
 ---> db61ff73c0b5
Step 3/3 : COPY 2.txt /2.txt
 ---> f1129e47fc12
Successfully built f1129e47fc12
Successfully tagged demo:latest

Now modify 2.txt and then rebuild the image:

$ echo two > 2.txt
$ docker build -t demo:latest .
Sending build context to Docker daemon   5.12kB
Step 1/3 : FROM alpine:latest
 ---> 9c6f07244728
Step 2/3 : COPY 1.txt /1.txt
 ---> Using cache
 ---> db61ff73c0b5
Step 3/3 : COPY 2.txt /2.txt
 ---> 75ba7d786049
Successfully built 75ba7d786049
Successfully tagged demo:latest

The second build stage shows Using cache because the contents of 1.txt haven’t changed. The intermediate layer with ID db61ff73c0b5 gets reused for the new build.

Disabling the Cache

You can disable use of the intermediate layer cache by including the --no-cache flag when you run docker build:

$ echo second > 2.txt
$ docker build --no-cache -t demo:latest .
Sending build context to Docker daemon   5.12kB
Step 1/3 : FROM alpine:latest
 ---> 9c6f07244728
Step 2/3 : COPY 1.txt /1.txt
 ---> 1590b2407dd4
Step 3/3 : COPY 2.txt /2.txt
 ---> afb31630ce32
Successfully built afb31630ce32
Successfully tagged demo:latest

This time a new image layer, ID 1590b2407dd4, has been created by the second build stage, even though 1.txt remains unmodified.

You can use the --no-cache flag to force a rebuild when you suspect the cache is stale or you want to start from scratch. Build performance will be reduced because Docker will need to recreate every layer.

Pulling Updated Base Images

Another form of caching concerns the base images which your Dockerfile references in its FROM instructions. The example image above uses alpine:latest as its base. Docker won’t automatically pull an updated version of alpine:latest, unless the image doesn’t already exist on your host.

This means the first build of a Dockerfile will pull down the base images you need, as long as you don’t already have them. Subsequent rebuilds won’t refresh the images so you could be building on an outdated base. Building the image on a different Docker host might not produce the same output if that host pulls a newer version of the base.

You can force Docker to check for updated base images at build time by adding the --pull flag to your docker build command. This is separate to --no-cache. Using --pull will retrieve the image tag’s manifest from its registry and compare it to the version on your machine. The new image will be pulled from the registry when there’s a discrepancy in the manifests.

$ docker build --no-cache --pull -t demo:latest .
Sending build context to Docker daemon   5.12kB
Step 1/3 : FROM alpine:latest
latest: Pulling from library/alpine
Digest: sha256:bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad
Status: Image is up to date for alpine:latest
 ---> 9c6f07244728
Step 2/3 : COPY 1.txt /1.txt
 ---> 4fee970dfaab
Step 3/3 : COPY 2.txt /2.txt
 ---> 60d2e3fff0fb
Successfully built 60d2e3fff0fb
Successfully tagged demo:latest

The above example shows how the build output changes when the --pull flag is used. Docker tries to pull the Alpine base image, even though it’s already on the machine from the earlier example builds. The image digest (SHA) is printed to the terminal. In this case the digest is unchanged from the local version so Docker reports that the image is already up to date.

The --no-cache and --pull flags can be used independently or in combination. Adding them both gives you the cleanest slate for starting your build, forcing Docker to check for updated base images and disregard any previously created layers. It’s equivalent to running the build on a newly installed Docker host.

Using Docker Compose

Docker Compose supports both the --no-cache and --pull flags too. They have the same effect as their docker build counterparts.

# Compose v2
$ docker compose build --no-cache --pull

# Compose v1
$ docker-compose build --no-cache --pull

Cleaning the Build Cache

You can clean the build cache to guarantee it’s disused. This also helps to free up excess disk space consumed by cached build layers.

Run the docker builder prune command to empty your cache. It only works when you’re building images with the modern BuildKit build engine.

$ docker builder prune

Running the command without arguments only removes the dangling build cache. This relates to caches that relate to images no longer present on your host. Add the -a flag to completely empty the cache, including layers that are used by images:

$ docker builder prune -a

Pruning also accepts a --filter flag that can be used to target caches modified before or since a particular time period.

# Delete caches modified in the past two hours
$ docker build prune --filter since=2h

# Delete caches modified more than two hours ago
$ docker build prune --filter until=2h

Summary

The Docker build cache improves performance by reusing intermediate image layers between builds. This avoids wasted work to recreate layers that already exist and haven’t changed. While the build cache is generally desirable, there are scenarios where you might want to run a build without it. Adding the --no-cache flag to your builds provides an accurate perspective of what the build would produce when run on a new host.

Stale base images need to be considered alongside the build cache too. Docker reuses local versions of base images by default, which can cause you to build new images on an outdated base. Using the --pull flag forces Docker to check for updated base images before it starts the build, giving you greater consistency across different environments.

FOLLOW us ON GOOGLE NEWS

 

Read original article here

Denial of responsibility! My droll is an automatic aggregator of the all world’s media. In each content, the hyperlink to the primary source is specified. All trademarks belong to their rightful owners, all materials to their authors. If you are the owner of the content and do not want us to publish your materials, please contact us by email – [email protected]. The content will be deleted within 24 hours.

Leave a comment