Home Explore Blog CI



docker

1st chunk of `content/manuals/build/cache/optimize.md`
2af69b63c577a356aafbab579396c1dffcf3369fafac91740000000100000fb3
---
title: Optimize cache usage in builds
description: An overview on how to optimize cache utilization in Docker builds.
keywords: build, buildkit, buildx, guide, tutorial, mounts, cache mounts, bind mounts
aliases:
  - /build/guide/mounts/
---

When building with Docker, a layer is reused from the build cache if the
instruction and the files it depends on hasn't changed since it was previously
built. Reusing layers from the cache speeds up the build process because Docker
doesn't have to rebuild the layer again.

Here are a few techniques you can use to optimize build caching and speed up
the build process:

- [Order your layers](#order-your-layers): Putting the commands in your
  Dockerfile into a logical order can help you avoid unnecessary cache
  invalidation.
- [Keep the context small](#keep-the-context-small): The context is the set of
  files and directories that are sent to the builder to process a build
  instruction. Keeping the context as small as possible reduces the amount of data that
  needs to be sent to the builder, and reduces the likelihood of cache
  invalidation.
- [Use bind mounts](#use-bind-mounts): Bind mounts let you mount a file or
  directory from the host machine into the build container. Using bind mounts
  can help you avoid unnecessary layers in the image, which can slow down the
  build process.
- [Use cache mounts](#use-cache-mounts): Cache mounts let you specify a
  persistent package cache to be used during builds. The persistent cache helps
  speed up build steps, especially steps that involve installing packages using
  a package manager. Having a persistent cache for packages means that even if
  you rebuild a layer, you only download new or changed packages.
- [Use an external cache](#use-an-external-cache): An external cache lets you
  store build cache at a remote location. The external cache image can be
  shared between multiple builds, and across different environments.

## Order your layers

Putting the commands in your Dockerfile into a logical order is a great place
to start. Because a change causes a rebuild for steps that follow, try to make
expensive steps appear near the beginning of the Dockerfile. Steps that change
often should appear near the end of the Dockerfile, to avoid triggering
rebuilds of layers that haven't changed.

Consider the following example. A Dockerfile snippet that runs a JavaScript
build from the source files in the current directory:

```dockerfile
# syntax=docker/dockerfile:1
FROM node
WORKDIR /app
COPY . .          # Copy over all files in the current directory
RUN npm install   # Install dependencies
RUN npm build     # Run build
```

This Dockerfile is rather inefficient. Updating any file causes a reinstall of
all dependencies every time you build the Docker image even if the dependencies
didn't change since last time.

Instead, the `COPY` command can be split in two. First, copy over the package
management files (in this case, `package.json` and `yarn.lock`). Then, install
the dependencies. Finally, copy over the project source code, which is subject
to frequent change.

```dockerfile
# syntax=docker/dockerfile:1
FROM node
WORKDIR /app
COPY package.json yarn.lock .    # Copy package management files
RUN npm install                  # Install dependencies
COPY . .                         # Copy over project files
RUN npm build                    # Run build
```

By installing dependencies in earlier layers of the Dockerfile, there is
no need to rebuild those layers when a project file has changed.

## Keep the context small

The easiest way to make sure your context doesn't include unnecessary files is
to create a `.dockerignore` file in the root of your build context. The
`.dockerignore` file works similarly to `.gitignore` files, and lets you
exclude files and directories from the build context.

Here's an example `.dockerignore` file that excludes the `node_modules`
directory, all files and directories that start with `tmp`:

```plaintext {title=".dockerignore"}

Title: Optimize Cache Usage in Docker Builds
Summary
This document provides techniques to optimize Docker build caching for faster builds. Key strategies include ordering Dockerfile layers logically to minimize cache invalidation, keeping the build context small by using a `.dockerignore` file, utilizing bind mounts to avoid unnecessary layers, leveraging cache mounts for persistent package caching, and using an external cache for sharing build cache across multiple builds and environments.