How to use .dockerignore and its importance
This article provides an overview of .dockerignore files, their benefits, syntax and real-world examples. There are various use cases for .dockerignore files, such as reducing build time and security risks. Let's learn how to use .dockerignore for efficient Docker image creation.,
What is a .dockerignore file?
A .dockerignore is a configuration file that describes files and directories that you want to exclude when building a Docker image.
Usually, you put the Dockerfile in the root directory of your project, but there may be many files in the root directory that are not related to the Docker image or that you do not want to include. .dockerignore is used to specify such unwanted files and not include them in the Docker image.
Benefits of using a .dockerignore file
The .dockerignore file is helpful to avoid inadvertently sending files or directories that are large or contain sensitive files to the daemon or avoid adding them to the image using the ADD or COPY commands. In the following, we will discuss specific benefits and use cases.
Cache invalidation
If you have frequently updated files (git history, test results, etc.) in your working directory, the cache will be regenerated every time you run Docker build. Therefore, if you include the directory with such files in the context, each build will take a lot of time. Consequently, you can prevent the cache from generating at build time by specifying .dockerignore.
This is a directory like .DS_Store
, for example. These are unnecessary for creating Docker images, so you should add them.
Reduces the image size
By specifying files not to be included in the context in .dockerignore, the size of the image can be reduced. Reducing the size of the Docker image has the following advantages These benefits are important because the more instances of a service you have, such as microservices, the more opportunities you have to exchange Docker images.
- Faster speed when doing Docker pull/push.
- Faster speed when building Docker images.
In addition, it is recommended to add directories such as node_modules
to .dockerignore because of their large file size.
Security Issues
If a Docker image file contains sensitive information such as credentials, it becomes a security issue. For example, uploading a Docker image containing files with credential information such as .aws
or .env
to a Docker repository such as the public DockerHub will cause those credential information to be compromised.
In the past, there have been cases where credential information and source code, and passwords have been compromised by uploading to DockerHub.(Twitter, 2016)
Don't forget to exclude the .git
directory at this point. If you have committed sensitive information in the past but have not erased it, it can cause serious problems. Git history is not required to be included in Docker images, so be sure to include it in your .dockerignore file.
How .dockerignorefile works
Before sending the Docker build context (Dockerfile, files you want to send inside the Docker image, and other things needed when building the Docker image) to the Docker daemon, in the root directory of the build context look for a file named .dockerignore in the root directory of the build context. If this file exists, the CLI will exclude any files or directories from the context that match the pattern written in the file. Therefore, the files and directories described in the .dockerignore file will not be included in the final built Docker image.
How to create a .dockerignore file?
If you know how it works, you will understand how to create it. The .dockerignore file works by creating a file named .dockerignore in the build context root.
Note that the build context root here is the path used by docker build, not the location of the Dockerfile.
docker build -f path/to/Dockerfile dir
In the above example, dir is the build context root. In other words, in the above example, .dockerignore should be placed in the dir directory.
.dockerignore syntax
All you have to do is write the file's name you want to exclude from the Docker build context. This is roughly similar to the way you would write a .gitignore. Let's take a look at the detailed syntax below.
Comments
First, lines beginning with #
will be interpreted as comments.
# This is just a comment.
README.md
Using wildcards, etc.
By using wildcards in the description, you can specify a target file regardless of which directory it is in. The following is an example of specifying a file named target
in any directory one level below the build context root.
*/target
On the other hand, if you want to specify a specific file name, not just a file hierarchy, use **
.
**/target
The following also excludes files whose names are extended by one character from target
. For example, target1
and targetA
are excluded.
target?
Specifying exceptions
If you want to exclude a specific file from the list of files specified with .dockerignore
, use the !
exception character. The following is an example where files with .md
extension are not included in the Docker image, but only README.md
is included.
*.md
!README.md
Syntax difference between .dockerignore and .gitignore
By the way, I explained that .dockerignore and .gitignore are similar, but there are some differences in syntax.
In .gitignore, the file or directory name is ignored in any hierarchy below the .gitignore file, but in .dockerignore, all paths must be relative to the way where .dockerignore is located. However, in .dockerignore, all paths must be listed relative to the path. Let's take a concrete example.
Suppose you have the following files in the current directory
target
src/target
path/to/target
For example, suppose you write the following in .gitignore:
target
In that case, files like the following will be ignored.
target
src/target
path/to/target
On the other hand, you can write the following in .dockerignore:
target
In this case, unlike .gitignore, only the following files will be ignored. In other words, you need to specify the directory in .dockerignore.
target
If you want to exclude files in other directories as in the .gitignore example, you can put the following in .dockerignore:
**/target
Example of .dockerignore file (Best Practice)
So, what kind of files and directories should you actually specify when writing the .dockerignore file? The following are some examples from projects using several languages.
Node.js
In the case of Node.js projects, it is effective to exclude files such as node_modules and npm-debug.
**/node_modules/
**/dist
.git
npm-debug.log
.coverage
.coverage.*
.env
.aws
Python
In the case of Python, you can efficiently build Docker images by excluding cache files such as pycache and files such as pip-log.
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env
pip-log.txt
pip-delete-this-directory.txt
.tox
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.log
.git
.mypy_cache
.pytest_cache
.hypothesis
Source:https://github.com/GoogleCloudPlatform/getting-started-python/blob/main/optional-kubernetes-engine/.dockerignore
FAQ about using .dockerignore
Why is my .dockerignore not working?
You are likely specifying the file path incorrectly. For example, notations starting with /
, such as /target
are not supported.
The way to specify the file path in .dockerignore is based on the specification of the file path package in the go language; see the following page for details. https://pkg.go.dev/path/filepath#Match
Should I add node_modules to .dockerignore?
As described in the Docker blog below, node_module does not need to be included in the Docker image. In other words, it should be included in .dockerignore. https://www.docker.com/blog/keep-nodejs-rockin-in-docker/
It would help if you did not confuse the node_modules on the Docker host with the node_modules in the container because, on macOS and Windows, Docker Desktop will bind-mount the code across OS walls. On macOS and Windows, Docker Desktop bind mounts code across OS barriers, which may cause problems where binaries installed with npm for the host OS cannot be executed on the container OS.
Summary
So far, we have described the advantages of using .dockerignore, its syntax, and its usage. I hope you now understand why the .dockerignore file is so important and why you should remember to write it.
The .dockerignore file is just as easy to specify as the .gitignore file, so don't forget to create it.