قالب وردپرس درنا توس
Home / Tips and Tricks / Understanding the Docker Build Context (Why You Should Be Using Dockerignore) – CloudSavvy IT

Understanding the Docker Build Context (Why You Should Be Using Dockerignore) – CloudSavvy IT



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 Dockerfile

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?

Here̵

7;s a simple one docker build order:

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.

Within you 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 Dockerfile

FROM node:latest
WORKDIR /my-app
COPY package.json package.json
COPY package-lock.json package-lock.json
COPY src/ .
RUN npm install

So simple 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.

The Dockerfile runs 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 Dockerfile

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 .gitignore

node_modules/

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.

Conclusion

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.


Source link