We know that we can run our docker images on cloud services which provide high computations in low cost prices. So, one might wonder why we need to optimize a docker image. Think of a situation where you have copied a large file in your docker container and you actually don’t need it. It’s obvious that it will increase the size of the docker image, it will increase the overall build time of the image and would cause a lot of caching issues as well. So, why not use a simple technique to avoid all these issues and improve the overall performance of the docker build process.
Similar to a .gitignore file, a .Dockerignore files allows you to mention a list of files and/or directories which you might want to ignore while building the image. This would definitely reduce the size of the image and also help to speed up the docker build process. To understand the whole process, we first need to understand what Docker build context is.
We know that Docker is basically a Client-Server application. It has a docker client which we run on our local machine through command line tools and a docker server also known as docker daemon. The Docker client which runs through the command line needs to talk to the Docker server (Daemeon) and that’s how instructions are carried out. One of the tasks is to build a docker image. Also, another thing to note is that the docker server can run on a remote machine, a local machine or even on cloud.
When we try to build a docker image, we need to send the files to the docker server. These files are basically the build context. These files are archived into a .tar file by the docker client and then they are uploaded to the docker server.
Before sending the files over to the docker server, the docker client (Command Line Interface) starts searching for a file called .dockerignore in the Build Context’s root directory. If it finds such a file, the CLI (Client) will modify the build context to exclude those files and directories which are mentioned inside the .dockerignore file.
It is obvious that if the build context is smaller in size, the size of the docker image will be smaller and hence uploading an smaller image to any cloud service or sending them to another remote server would be less costly compared to large image sizes.
It is important to understand that the most common practice is to copy the entire directory or the build context to create an image using the following command.
WORKDIR /usr/src/app COPY . .
Now, if we decide to make a change in the build context, the build process would create a new image layer every time we do so which is quite expensive if the size of the docker image is large or in other words , if it contains large unnecessary files. Any change would lead to cache invalidation and would break the cache for the following commands as well. Thus, it is always a better practice to remove large unnecessary files from the build context.
You might have some important source files or files that contain secret keys or passphrases in your build context. You might not want to expose such important files into the final docker image. For example, exposing your .git folder inside your docker image. Thus, it’s always recommended to ignore such files and folders by mentioning them into .dockerignore file.
Here are a few examples of how you can mention files, folders and directories in your .dockerignore file.
#Ignore the logs directory logs/ #Ignoring the password file passwords.txt #Ignoring git and cache folders .git .cache #Ignoring all the markdown and class files *.md **/*.class
Another question might arise here, can and should we ignore the Dockerfile while building the docker image?
The answer to this question mostly depends upon the preference of the developer. If you want to allow your users to know about the rules of creating your docker image, you should not mention it in the .dockerignore file. If you want to keep it a secret, you could add it otherwise.
To conclude, it is always recommended that you create a .dockerignore file in your build context to make your docker images small and secure and make your build process faster.