Docker 构建与 .dockerignore 的工作机制详解

在使用 Docker 构建镜像时,我们经常会遇到 .dockerignore 的问题,尤其是在多项目(多子目录)共存的场景下。


一、问题背景

假设你的项目目录结构如下:

.
├── .dockerignore   # 用于构建子目录 B 的镜像
├── A/              # 子项目 A,有独立的 Dockerfile
│   └── Dockerfile
└── B/              # 子项目 B
    └── Dockerfile

其中:

  • 根目录有一个 .dockerignore,内容是为了 B 的构建准备的,例如:

    *
    !B/**
    

    这意味着:构建时除了 B/,其他目录(包括 A/)都会被忽略。

  • 子目录 A 也有一个独立的 Dockerfile,你希望这样构建:

    docker build -f ./A/Dockerfile .
    

    注意这里的 . —— 表示根目录是构建上下文。


二、问题现象

当你在构建子目录 A 时,Dockerfile 中使用 COPY 或 ADD 指令复制文件,例如:

COPY . /app

却发现报错:

COPY failed: file not found in build context or excluded by .dockerignore

原因是:根目录的 .dockerignore 把 A/ 目录屏蔽掉了,构建上下文里根本没有 A 的文件。

因为,以根目录作为构建上下文时,会默认读取根目录的.dockeriginore,而这个.dockeriginore原本是为了B项目准备的


三、Docker 构建与 .dockerignore 的工作流程

Docker 在构建时会经历以下几个步骤:

  1. 确定构建上下文
    你运行的命令:

    docker build -f ./A/Dockerfile .
    

    指定了 . 作为构建上下文,即根目录。

  2. 读取 .dockerignore
    Docker 会在构建上下文根目录查找 .dockerignore 文件,并根据规则过滤掉文件和目录。

  3. 打包构建上下文
    过滤后的文件被打包成一个 tar 包,传递给 Docker Daemon。

  4. 执行构建
    Docker Daemon 使用这个上下文,以及指定的 Dockerfile 开始执行构建步骤。

关键点:-f 只改变 Dockerfile 的位置,不会改变构建上下文路径。
所以即使你指定了 -f ./A/Dockerfile,只要构建上下文是根目录,A 目录是否被包含,仍然取决于根目录下的 .dockerignore。


四、解决方案

针对这种场景,有几种常见的解决方式:

方案一:改变构建上下文(推荐)

直接把子目录作为构建上下文:

docker build -f ./A/Dockerfile ./A

这样 .dockerignore 就会在 A/ 目录下生效,而不会受到根目录 .dockerignore 的影响。


方案二:为每个子项目维护独立的 .dockerignore

  • 在 A/ 和 B/ 目录下各自维护 .dockerignore。

  • 构建时指定子目录为上下文:

    docker build -f Dockerfile ./A
    docker build -f Dockerfile ./B
    

方案三:动态切换 .dockerignore

如果必须以根目录作为上下文,可以在构建前,将对应项目的 .dockerignore 复制到根目录,例如:

cp A/.dockerignore .dockerignore
docker build -f ./A/Dockerfile .

这种方式比较 Hack,不够优雅,但在某些 CI/CD 场景下会用到。


五、总结

  • .dockerignore 的作用范围是 构建上下文的根目录。
  • -f 参数只决定 Dockerfile 的路径,不影响上下文。
  • 如果 .dockerignore 把子目录屏蔽掉了,那么这个子目录的文件就不会出现在构建上下文中,COPY/ADD 就会失败。

最优雅的方式:以子目录作为构建上下文,并在子目录下维护自己的 .dockerignore。


https://github.com/0voice

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐