Manage build cache with --cache-from and --cache-to
In this step, you will learn how to manage the Docker build cache using the --cache-from
and --cache-to
flags. The build cache can significantly speed up subsequent builds by reusing layers from previous builds. --cache-from
allows you to specify an image to use as a cache source, and --cache-to
allows you to export the build cache to a specified location (like a registry or a local directory).
First, ensure you are in the ~/project
directory.
cd ~/project
Let's modify our Dockerfile
slightly to simulate a change that would normally break the cache. We'll add a simple RUN
instruction.
Open the Dockerfile
with nano
:
nano Dockerfile
Add the following line after the ARG
instruction in the builder
stage:
RUN echo "Adding a new layer"
The updated Dockerfile
should look like this:
## Stage 1: Builder stage
FROM ubuntu:latest as builder
ARG GREETING="Hello from build argument!"
RUN echo "Adding a new layer"
RUN echo $GREETING > /app/greeting.txt
## Stage 2: Final stage
FROM ubuntu:latest
COPY --from=builder /app/greeting.txt /greeting.txt
CMD ["cat", "/greeting.txt"]
Save the Dockerfile
and exit nano
.
Now, let's build the image again without using any specific cache options. Docker will automatically use the local cache if available.
docker build -t my-cached-image .
You should see that some layers are built from scratch because we added a new instruction, invalidating the cache for subsequent instructions.
Now, let's simulate a scenario where you might want to use a previously built image as a cache source, perhaps from a registry or another build. For demonstration purposes, we will use the my-cached-image
we just built as the cache source for a new build.
First, let's make a small change to the Dockerfile
again to simulate another modification.
Open the Dockerfile
:
nano Dockerfile
Change the message in the new RUN
instruction:
RUN echo "Adding another new layer"
The updated Dockerfile
should look like this:
## Stage 1: Builder stage
FROM ubuntu:latest as builder
ARG GREETING="Hello from build argument!"
RUN echo "Adding another new layer"
RUN echo $GREETING > /app/greeting.txt
## Stage 2: Final stage
FROM ubuntu:latest
COPY --from=builder /app/greeting.txt /greeting.txt
CMD ["cat", "/greeting.txt"]
Save and exit nano
.
Now, build the image again, but this time use the --cache-from
flag to specify my-cached-image
as the cache source.
docker build --cache-from my-cached-image -t my-cached-image-from .
You should observe that Docker attempts to use layers from my-cached-image
. The layer corresponding to the first RUN
instruction will likely be rebuilt because the instruction changed, but subsequent layers might be pulled from the cache if they match.
The --cache-to
flag is used to export the build cache. This is particularly useful in CI/CD pipelines to share cache between builds. To use --cache-to
, you typically need to use a build driver that supports cache export, such as the docker-container
driver.
First, let's install Docker Compose, which is often used with buildx.
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
Now, let's create a buildx builder instance.
docker buildx create --use
Now, let's build the image and export the cache to a local directory. We'll use the local
cache exporter.
docker buildx build --cache-to type=local,dest=./build-cache -t my-exported-cache-image . --load
docker buildx build
: Uses the buildx tool for building.
--cache-to type=local,dest=./build-cache
: Exports the cache to a local directory named build-cache
in the current directory.
-t my-exported-cache-image
: Tags the resulting image.
.
: Specifies the build context (current directory).
--load
: Loads the built image into the local Docker image cache.
You should see output indicating the build and the cache export. A build-cache
directory will be created in your ~/project
directory.
Now, let's simulate a clean build environment and try to build using the exported cache. First, let's remove the images we built.
docker rmi my-cached-image my-cached-image-from my-exported-cache-image
Now, build the image again, this time using the exported cache as the source.
docker buildx build --cache-from type=local,src=./build-cache -t my-imported-cache-image . --load
--cache-from type=local,src=./build-cache
: Imports the cache from the local directory build-cache
.
You should observe that Docker uses the layers from the exported cache, significantly speeding up the build process compared to building from scratch.