The Docker build context refers to the files and folders available to the Docker engine when you run it
docker buildAnything not included in the build context cannot be accessed by commands in your
You must use your
docker build to keep your build contexts small. Accidentally recording unnecessary files can result in too large a build context, which will lead to longer builds.
What is the build context?
docker build . -t my-image:latest
This will create a Docker image using the
Dockerfile found in your workbook. The resulting image will be tagged as
my-image:latestalthough this detail is not important to this tutorial.
Dockerfile, you will probably use
COPY to add files and folders to your image:
FROM httpd:latest COPY index.html /usr/local/apache2/htdocs/index.html COPY css/ /usr/local/apache2/htdocs/css/
This example copies it
index.html file and
css directory in your container. At first glance, it looks like the
COPY statement simply points to a path resolved relative to your workbook.
This is not quite the case.
COPY can only access resources available in the build context. In this example, the build context is the working folder, so the files and folders in it are available. By default, Docker uses the contents of the directory passed to
docker build as the build context.
Why is the build context used?
The build context is important because the Docker CLI and Docker Engine may not be running on the same computer. When you run
docker build, the CLI sends the files and directories to be built to the Docker engine. This set of files and folders becomes the build context.
In addition, not every build context is as easy as reusing your workbook. Docker also supports Git repository URLs as the path provided to
docker buildIn this case, the build context becomes the contents of the specified repository.
The default “include all” behavior of the build context is fine for many small repositories. Problems become apparent as soon as you add files to your workbook that are not included in your
DockerfileResources such as pre-built binaries, documentation files, and dependency libraries are included in the build context, even though they are redundant.
Including too many assets in the build context can cause a loss of performance. You unnecessarily copy files that will never be used. The delay will be especially evident if you are connected to an external Docker daemon or if you are using a slow mechanical hard drive. You will see “send build context to Docker daemon” in your shell while the copy is complete.
Docker itself tries to minimize redundant copying. The BuildKit build backend – used since Docker 18.09 – has added support for incremental transfers. This means that Docker usually only needs to copy files that have been added or changed since your last build. It will still copy the whole batch on the first build.
Exclude resources from the build context
To fix wasteful copying for good, you need to tell Docker what to omit from the build context. Let’s start making one
FROM node:latest WORKDIR /my-app COPY package.json package.json COPY package-lock.json package-lock.json COPY src/ . RUN npm install
Dockerfile can be used by an application written in Node.js. Using Node.js programs
npm as their package manager. Packages are installed on a
node_modules folder. When you run
npm install locally, during development, the packages are downloaded to the
node_modules folder in your workbook.
npm install themselves to acquire the dependencies. This ensures that the image is completely self-contained. There is no need to use it local
node_modules folder, because it is not used by the
Despite this, Docker will still get the
node_modules folder in the default build context. To rule it out, create a
.dockerignore file in your working directory. This file has a similar syntax to
All paths listed in
.dockerignore is excluded from the build context. You have to take care of that
.dockerignore will be kept up to date with changes to the file system structure of your project. You can significantly reduce the time to copy Docker build context by checking that only relevant paths (those actually through your
Dockerfile) are present in the build context.
In the case of our example, the
node_modules folder can contain thousands of files if we have many dependencies in our project. Copying to the Docker daemon as part of the build context can take a few seconds and would be a wasteful operation. The
Dockerfile ignores them completely and fetches its own dependencies through
npm install instead.
Other build context issues
Do not use
.dockerignore can also introduce other problems. A Docker file with this line is particularly problematic:
COPY . /my-app
This will copy everything in your workbook. This may seem like a good idea until you realize that your
.git history and any secret files will also end up in your container.
Copying an unfiltered build context also prevents Docker layer caching from working effectively. Like something in your working directory will likely change between builds, Docker would
COPY instruction every time. This would create a new layer – and new layers for any subsequent instructions – even if the items you are interested in haven’t changed.
Compress the build context
You can compress the build context to further improve build performance. Give the
--compress flag to
docker build to apply gzip compression. The compression takes place before the context is sent to the Docker daemon.
docker build . -t my-image:latest --compress
This can improve performance in some scenarios. However, the compression adds its own overhead: your system must now compress the context and the receiving Docker daemon must decompress it. Using compression can in some cases be even slower than copying the original files. Experiment with each of your images to see if you see an improvement.
The Docker build context defines the files available to copy in your
DockerfileThe build context is copied to the Docker daemon before the build begins.
Build contexts contain the contents of the directory or Git repository you passed by by default
docker buildYou can omit items from the build context with a
.dockerignore File. This increases efficiency by reducing the amount of redundant data passed to the Docker daemon.