一文看懂 .dockerignore
在 dockerfile
同级目录中创建名为 .dockerignore
的文件,用法与 .gitignore
类似,可以实现在构建镜像的时,不将某些文件夹或文件打入到镜像中。
以下示例会过滤 images、media 目录,以及 png、jpg 图片。
- .dockerignore
*/images/
*/media/
*.png
*.jpg
2
3
4
我们来看下这个示例,首先看下 dockerfile ADD 的内容,重点是 ADD book/docs/.vuepress/dist/ /usr/share/nginx/html/
这一行。
- dockerfile
FROM nginx:alpine
WORKDIR /usr/share/nginx/html
ADD book/docs/.vuepress/dist/ /usr/share/nginx/html/
ADD etc/nginx/nginx.conf /etc/nginx/nginx.conf
ADD etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
ADD etc/localtime /etc/localtime
EXPOSE 80
2
3
4
5
6
7
这是 book/docs/.vuepress/dist/other/else/
的目录结构,包含一个 media
文件夹
~$ ll other/else/
total 16
-rw-r--r--@ 1 spark staff 1.6K 8 1 16:15 enable-1000mbps.md
-rw-r--r--@ 1 spark staff 1.8K 7 27 17:57 max-values-per-tag.md
drwxr-xr-x@ 8 spark staff 256B 8 1 16:11 media
2
3
4
5
这是构建镜像后,运行容器并查看 other/else
目录的结构,可以看到其下没有 media
目录,已经被排除了。
~$ docker exec a95e5556c87c pwd
/usr/share/nginx/html
~$ docker exec a95e5556c87c ls -lh other/else
total 68K
-rw-r--r-- 1 root root 31.6K Aug 1 16:20 enable-1000mbps.html
-rw-r--r-- 1 root root 32.5K Aug 1 16:20 max-values-per-tag.html
~$
2
3
4
5
6
7
看完示例,接下来我们翻译一下 Docker 官方的 .dockerignoreopen in new window 的文档,不是硬翻译,带了自己的理解。
.dockerignore 详细介绍
在 docker build 过程中,Docker CLI 将 context 发送到 docker 守护进程之前,它会查看根目录中名为 .dockerignore
的文件。
如果 .dockerignore
存在,Docker CLI 将修改 context 以排除文件和目录。
这样可以将不必要的文件不打入到 Docker 镜像中,让 docker 镜像保持干净。
Docker CLI 将 .dockerignore
文件解释为换行符分隔的文件,也就是一行一个匹配规则。
context 的根目录为项目的根目录,也就是 dockerfile
的同级目录。你可以使用 /
开头的绝对路径,也可以使用相对路径。 比如 /foo/bar
和 foo/bar
效果是一样的。
在 .dockerignore
中,#
开头的行被认为是注释。
下面是一个 .dockerignore
文件示例:
# 注释
*/temp*
*/*/temp*
temp?
2
3
4
以下是对该 .dockerignore
文件的解释:
匹配规则 | 匹配结果 |
---|---|
# comment | 忽略 |
*/temp* | 排除根目录中(也就是不包含子目录)目录名称以 temp 开头的文件和目录。例如,排除普通文件 /somedir/temporary.txt ,目录 /somedir/temp 。 |
*/*/temp* | 排除根目录的二级子目录中以 temp 开头的文件和目录。例如,排除 /somedir/subdir/temporary.txt 。 |
temp? | 排除根目录中名称以 temp 开头,外加一个字符的文件和目录。例如,排除 /tempa 和 /tempb 。 |
匹配规则引用了 Go 的 filepath.Matchopen in new window 规则。预处理步骤会删除一行中首尾空格,同时使用 filepath.Cleanopen in new window 会忽略
.
和..
。预处理(preprocessing)后为空的行将被忽略。
除了 Go 的 filepath.Match 规则,Docker 还支持一个特殊的通配符字符串
**
匹配任意数量的目录(包括零)。例如,**/*.go
将排除所有目录中以.go
结尾的文件,包含根目录。
以 !
(感叹号)开头的行用来做例外,也就是说这些行不会被排除,仍然会打入到镜像中。以下是一个 .dockerignore
示例:
*.md
!README.md
2
除了 README.md
, 所有 Markdown 文件都将排除。
!
异常规则的位置会影响匹配结果:包含指定文件(例如下文示例中的 README-secret.md
匹配的 .dockerignore
的最后一行确定是包含还是排除该文件。看一下这个例子:
*.md
!README*.md
README-secret.md
2
3
context 中不包含任何 Markdown 文件,除了 README 开头的 md
、README-secret.md
文件。
现在我们看下这个例子:
*.md
README-secret.md
!README*.md
2
3
context 中包含 README-secret.md
在内的所有 README 文件,不包含剩下 Markdown 文件。README-secret.md
没有被排除,因为 !README*.md
包含 README-secret.md
并且 !README*.md
在最后。
你甚至可以使用 .dockerignore
文件来排除 Dockerfile
和 .dockerignore
文件。这些文件仍然发送到 Deamon 进程,但 ADD
和 COPY
指令不会将它们复制到镜像中。
最后,您可能希望指定要包含在 context 中,而不是排除哪个。为此,请将 *
放在第一行,后跟一个或多个 !
异常模式。
** 注意事项 **
由于历史原因,
.
模式被忽略。
reference
- [1] Docker. .dockerignore fileopen in new window