.dockerignore 速查表 - Docker 构建上下文忽略规则大全

写 Dockerfile 时若漏配 .dockerignore,docker build . 会把 node_modules、.git 整个打包进构建上下文,拖慢构建还虚增镜像体积。这份速查覆盖 5 组:基础语法、通配符、常见忽略项、与 .gitignore 的差异,以及瘦身技巧。写出模板后用 docker build 验证上下文大小,误删文件时记住 ! 取反只会对已被忽略的项生效。读完后你能为项目配一份安全且精简的 .dockerignore。

配置格式·共 25 条命令·最后更新 2026-08-02
.dockerignoredocker构建上下文config忽略

基础语法 Basic Syntax 5

node_modules
忽略名为 node_modules 的文件或目录
*.log
忽略所有 .log 文件
tmp/
只忽略根目录下的 tmp 目录(带斜杠)
**/tmp
忽略任意层级的 tmp 目录
# comment
井号开头为注释行;空行会被直接忽略

通配符 Glob 6

*
匹配任意数量非分隔符字符
?
匹配单个非分隔符字符
**
匹配任意层级目录
[abc]
匹配括号内任一字符
*.tmp
忽略所有 .tmp 文件
dist/*
忽略 dist 下一级所有内容(保留 dist 目录本身)

常见忽略项 Common Ignores 6

.git
不把 git 仓库打进构建上下文
node_modules
依赖目录,通常已在镜像内安装
.env
不要泄漏密钥到构建环境
Dockerfile
忽略自身(极少需要)
*.md
忽略文档类文件
.dockerignore
忽略自身不影响当前构建

与 .gitignore 差异 4

!node_modules/important
用 ! 取反,重新包含被忽略项
Dockerfile 不读 .gitignore
.dockerignore 与 .gitignore 相互独立
构建上下文 = docker build .
docker 先按 .dockerignore 裁剪上下文再发给 daemon
COPY 仍受路径限制
.dockerignore 只影响上下文,不限制 COPY 目标

瘦身技巧 Slimming 4

**/*.pyc
忽略所有编译缓存
.cache/
忽略本地缓存目录
coverage/
忽略测试覆盖率报告
tests/
忽略测试目录减小上下文

命令示例

一份够用的基础模板

.git node_modules .env *.log **/*.pyc .cache/ coverage/ tests/

前四行覆盖版本库、依赖、密钥与日志,是最常被漏掉也最危险的几类;后四行是瘦身项,其中 **/*.pyc 跨所有层级匹配编译缓存,带斜杠的 .cache/ 只限定根目录。

通配符三种写法的实际含义

*.log tmp/ **/tmp dist/*

*.log 匹配任意层级的 .log 文件;tmp/ 只排除根下那一个目录;**/tmp 排除所有层级的 tmp;dist/* 只排除 dist 下一层内容而保留 dist 目录本身,目录是否需要保留决定了该用哪种。

取反重新包含:位置决定是否生效

node_modules !node_modules/important

取反必须写在忽略规则之后,因为规则从上往下匹配、后写的覆盖先写的。这里的效果是整个 node_modules 不进上下文,但其中 important 目录被重新包含进来。

与 .gitignore 的边界:三条容易记混的事实

# comment .dockerignore

井号起头是注释,空行直接忽略;忽略自身不影响当前构建但少了它就无法在镜像里查规则。Docker 不读 .gitignore,两份文件必须各写一份。

常见坑与注意事项

  • .dockerignore 只影响送进构建上下文的内容,不限制 COPY 的目标路径,别把它当成 Dockerfile 路径安全的一部分。
  • 用 ! 取反前必须确认该路径已被前面的规则忽略过;没有被忽略的路径写取反是空操作,不会让它进包。
  • .env 一旦进入上下文就会留在镜像层里,即使后续删除文件也删不掉那一层;密钥类文件必须从一开始就在忽略列表里。
  • dist/* 保留目录本身、dist/** 会连目录一起排除,需要保留空目录做挂载点时别选错写法。
  • .dockerignore 与 .gitignore 互相独立,把同一份文件复制过去当共用是最常见的失效原因。

提示

  • 不配 .dockerignore 时,docker build . 会把当前目录全部发给 daemon,node_modules 和 .git 会让上下文巨大。
  • 带斜杠的 tmp/ 只匹配根目录 tmp,不带斜杠的 tmp 会匹配任意层级的 tmp。
  • .dockerignore 与 .gitignore 互不影响,不能共用同一份文件。
  • 用 ** 可跨层级匹配目录,如 **/__pycache__ 忽略所有 Python 缓存。

常见问题

不配 .dockerignore,docker build . 到底会传什么?

当前目录的全部内容,一个字节不过滤。构建上下文是整个目录树原样交给 daemon,忽略只发生在 .dockerignore 列出的条目上。所以一个没配任何忽略规则的仓库会把 .git 历史、node_modules、构建产物、本地日志甚至 .env 一起打包发送——构建变慢只是后果之一,更严重的是密钥被打进镜像层,即使后续删掉文件,层本身仍然留在镜像里。正确做法是从模板起步,先覆盖依赖目录、版本库与本地配置三类。

tmp/ 和 **/tmp 有什么区别?

带不带路径分隔符决定了匹配是否限定在根目录。tmp/ 带尾斜杠,只匹配构建上下文根下的那一个 tmp 目录;不带斜杠的 tmp 会匹配任意层级的同名文件或目录。**/tmp 则是显式的跨层级写法,语义上等价于不加斜杠的 tmp,但在多层嵌套的项目里可读性更好,也更容易让人一眼看出「我要忽略所有层级」。选择依据是意图:只想排除构建根下的临时产物就用 tmp/,想让任何位置的同名目录都不进包就用不带斜杠或 ** 的形式。

.dockerignore 和 .gitignore 能共用一份吗?

不能,两者语法相近但语义不同,各管各的。.gitignore 管的是版本库,.dockerignore 管的是构建上下文;Docker 不会读取 .gitignore,反之亦然,所以写一份就等于另一半场景完全失效。实践中的差别体现在取反语法上:! 可以重新包含被忽略的项,但它只能对已经被规则忽略的路径生效——如果前面没有任何规则忽略过它,这条取反就是空操作。

用 ! 取反重新包含某个文件,为什么没生效?

几乎总是因为取反写在了前面,或者没有前置规则命中过它。取反是「撤销已有忽略」,不是「显式包含」:如果 .env 本身从未出现在忽略列表里,!.env 就是一句多余的话;而如果先写了忽略规则、后面又用忽略规则把它重新盖回去,取反同样失效。规则按从上到下顺序匹配、后者覆盖前者,所以要取反的条目必须放在忽略它的规则之后。另外注意取反只会影响发送进上下文的内容,不会放开 COPY 的路径限制。

配好 .dockerignore 后怎么确认生效了?

看构建输出里传输上下文的那一步,或用构建镜像历史确认体积。排除规则多时最常见的错误是写法看似正确但层级没对上,于是文件仍在包里——所以每次改动后都重新构建一次,比凭记忆判断可靠。体积层面用 docker history 逐层看体积,定位是哪一层带进来的大文件,再回头补规则。经验上把 .git、依赖目录、本地配置、测试与覆盖率产物、缓存目录这几类先覆盖掉,剩余按需再加。

官方参考来源

下方为命令对应的官方权威文档,供你核对最新用法与深入查阅。

由 巧匠 维护

公开更新于 2026年8月2日,内容持续校对官方文档。

联系我们

命令或描述有误?提交反馈、商务合作或产品建议都可发送邮件给我们。

联系我们