构建上下文是docker build命令指定路径下所有文件的打包上传集合,服务端仅能访问该上下文内的文件;COPY等指令的源路径必须位于此上下文中,否则报错。

因为 docker build 上传给 Docker 守护进程的只是你指定路径下的文件,目录外的文件根本不会发过去——服务端连看都看不到,自然无法 COPY 或 ADD。
构建上下文就是客户端打包上传的整个目录
Docker 不是在本地执行构建,而是在服务端(dockerd)里做的。所以 docker build . 中的 . 不是“当前目录”这个概念,而是“你要打包发给服务端的根目录”。客户端会把这个路径下所有内容(递归)打成 tar 包,传给服务端;服务端解压后,才开始读 Dockerfile、执行 COPY 等指令。
这意味着:
-
COPY ../package.json /app/失败,不是语法错,是../package.json根本不在上传包里 -
COPY /home/user/config.yaml /app/必然报错Forbidden path outside the build context - 即使
Dockerfile放在/project/backend/Dockerfile,但你从/project运行docker build -f backend/Dockerfile .,上下文仍是/project整个目录
如何让 COPY 正确引用文件
关键不是“怎么绕过限制”,而是“怎么把需要的文件放进上下文”。常见做法有:
- 把要复制的文件(如
package.json、config.toml)提前拷贝进构建目录,再用相对路径引用 - 调整构建命令的上下文路径:比如文件在
../shared,就 cd 到上层,运行docker build -f backend/Dockerfile ./backend - 用
.dockerignore排除无关大文件(如node_modules、.git),避免无谓上传拖慢构建 - 不依赖
COPY时,改用构建参数或多阶段构建中从其他镜像提取——例如RUN curl -sSL https://example.com/config > /app/config
-f 和 . 的位置关系常被搞反
docker build -f 指定的是 Dockerfile 路径,.(或任意路径)指定的是上下文根路径,二者完全独立:
-
docker build -f ./Dockerfile.prod .:上下文是当前目录,Dockerfile.prod必须在当前目录下 -
docker build -f ../Dockerfile.dev ./src:上下文是./src,Dockerfile.dev在上层目录,但服务端只收到./src下的文件——所以Dockerfile.dev实际上是从客户端读取后单独发过去的,不参与上下文打包 - 错误写法:
docker build -f ./Dockerfile .却把./Dockerfile放在了./src里——客户端找不到文件,直接报Cannot locate specified Dockerfile
最易被忽略的一点:Windows 上用 WSL2 后端时,上下文路径若跨 Windows 文件系统(如 C:\)和 WSL 根文件系统(如 /home/),Docker Desktop 可能静默失败或性能极差——此时必须确保上下文路径落在 WSL 内部(如 /home/user/project),而非 /mnt/c/Users/...。











